home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-08-26 | 137.7 KB | 4,093 lines |
- /*
- * Title: SkyView
- * Author: N P Hawkes
- * (c) 1992
- * Purpose: View the sky from any point on the
- * Earth's surface, at any time in 20th
- * or 21st centuries.
- */
- #define VERSION "1.02"
-
- #include "event.h"
- #include "baricon.h"
- #include "res.h"
- #include "resspr.h"
- #include "win.h"
- #include "wimpt.h"
- #include "menu.h"
- #include "template.h"
- #include "dbox.h"
- #include "bbc.h"
- #include "os.h"
- #include "coords.h"
- #include "colourtran.h"
- #include "print.h"
- #include "werr.h"
- #include "visdelay.h"
- #include "sprite.h"
- #include "signal.h"
- #include "font.h"
- #include "kernel.h"
-
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <math.h>
- #include <time.h>
-
- #include "sv_header.h"
- #include "datime.h"
- #include "tvsats.h"
- #include "markers.h"
- #include "stars.h"
- #include "sun.h"
- #include "planets.h"
- #include "moon.h"
- #include "userobj.h"
-
- /********************************************************/
- /* CONSTANTS */
- /********************************************************/
-
- /*------------------------------------------------------*/
- /* Names */
- /*------------------------------------------------------*/
-
- #define APP_NAME "SkyView" /* Task name */
- #define ICON_NAME "!skyview" /* Icon Bar icon */
- #define HORIZ_NAME "Horiz" /* Horiz window id */
- #define VERT_NAME "Vert" /* Vert window id */
- #define OB_NAME "Observer" /* Observer dbox */
- #define INFO_NAME "Info" /* Info dbox */
- #define DEF_NAME "ObData" /* File of defaults*/
- #define SEL_INFO_NAME "SelInfo" /* Sel Info dbox */
-
- /*------------------------------------------------------*/
- /* Numbers */
- /*------------------------------------------------------*/
-
- #define DIR_BASE 1 /* Icon No. of North button in */
- /* Observer Details dbox */
- #define NO_ENTRY -1 /* Dummy entry number for a menu*/
- /* entry which does not exist. */
-
- /*------------------------------------------------------*/
- /* Main Menu Items */
- /*------------------------------------------------------*/
-
- #define MAIN_NAME APP_NAME
-
- #define MAIN_MENU_ITEMS "\
- >Program info, \
- Observer..., \
- ~Display, \
- ~Horizontal view, \
- ~Vertical view, \
- Print| \
- ~Select object, \
- ~See selection, \
- ~Selection info, \
- ~Cancel selection| \
- Quit"
-
- enum {item_info = 1,
- item_observer,
- item_display,
- item_horiz,
- item_vert,
- item_print,
- item_select,
- item_view,
- item_details,
- item_cancel,
- item_quit };
-
-
- /*------------------------------------------------------*/
- /* "View" Sub-menu Items */
- /*------------------------------------------------------*/
-
- #define VIEW_SUB_NAME "See selectn:"
-
- #define VIEW_SUB_MENU_ITEMS "\
- Now, \
- On rising, \
- On setting, \
- On culminating"
-
- enum {view_item_now = 1,
- view_item_rising,
- view_item_setting,
- view_item_culminating};
-
- /*------------------------------------------------------*/
- /* "Print" Sub-menu Items */
- /*------------------------------------------------------*/
-
- #define PRINT_SUB_NAME "Print:"
-
- #define PRINT_SUB_MENU_ITEMS "\
- Horiz. quadrant,\
- Vert. complete"
-
- enum {print_item_horizq = 1,
- print_item_vertc};
-
- /*------------------------------------------------------*/
- /* Other Sub-Menu Items */
- /*------------------------------------------------------*/
-
- #define SEL_SUB_NAME "Select:"
- #define DISP_SUB_NAME "Display:"
-
- /*------------------------------------------------------*/
- /* Miscellaneous Items */
- /*------------------------------------------------------*/
-
- #define sv_info_field 4 /* Field for version No. */
-
-
- /********************************************************/
- /* New types of variable */
- /********************************************************/
-
- /*------------------------------------------------------*/
- /* Structures and Function Types for the windows */
- /*------------------------------------------------------*/
-
- /* Set up a structure similar to a wimp_box, but */
- /* designed to suit the arguments of bbc_rectangle. */
- typedef struct {
- int x; /* x */
- int y; /* y */
- int w; /* width */
- int h; /* height */
- } rect_box;
-
- /* Define a type for a compass-drawing function, which */
- /* takes no arguments and returns an os_error pointer: */
- typedef os_error *comp_drawfntype(void);
-
- /* Define a type for a title-building function, which */
- /* takes a char pointer and a BOOL as argument and */
- /* returns void: */
- typedef void title_buildfntype(char *title, BOOL font_ok);
-
- /* Define a type for a title-writing function, which */
- /* takes a char pointer and a flag and returns an */
- /* os_error pointer: */
- typedef os_error *title_writefntype(char *title, BOOL font_ok);
-
- /* Structure containing information to particularise */
- /* the generic window-handling functions. */
- typedef struct {
- BOOL open; /* Open/Closed flag. */
- comp_drawfntype *compass_drawfn;/*Compass-drawing fn. */
- plotobj* listptr; /* Pointer to plotting list*/
- int number; /* No. of objects in list. */
- int selnum; /* ID of selected object. */
- rect_box sel_frame; /* Frame round selected obj*/
- wimp_box sel_bounds; /* Bounding box of frame */
- /* around selected object. */
- wimp_box wind_area; /* Area to be printed. */
- print_transmatstr matrix; /* Transfm matrix for print*/
- print_positionstr posn; /* Position for print o/p. */
- title_buildfntype *title_buildfn; /*Title-building fn.*/
- title_writefntype *title_writefn; /*Title-writing fn.*/
- } sv_windata;
-
- /*------------------------------------------------------*/
- /* Structure for Compass Label */
- /*------------------------------------------------------*/
-
- typedef struct {
- int len; /* Length of compass label - 1 */
- char name[3]; /* Character string for label */
- } c_label;
-
- /*------------------------------------------------------*/
- /* Structure for recording Module functions */
- /*------------------------------------------------------*/
-
- typedef struct {
- buildfntype *buildfn; /* Ptr to List Building fn. */
- selectfntype *selectfn; /* Ptr to Obj Selecting fn. */
- displayfntype *dispfn; /* Ptr to Disp Option fn. */
- infofntype *infofn; /* Ptr to Info function. */
- } fnliststr;
-
- /*------------------------------------------------------*/
- /* Structure for converting argument of Wimp_SetColour */
- /* into separate colour, gcol action and fore/back flag.*/
- /*------------------------------------------------------*/
-
- typedef union {
- int argument;
- struct {unsigned int w_colour :4;
- unsigned int gcol_act :3;
- unsigned int foreback :1;
- } fields;
- } ctrans_type;
-
- /********************************************************/
- /* FUNCTION PROTOTYPES */
- /********************************************************/
-
- static void sv_info_about_program(void);
- static void main_menuproc(void *handle, char *hit);
- static menu main_premenuproc(void *handle);
- static void view_sub_menuproc(char *hit);
- static BOOL sv_initialise(void);
- static BOOL create_window(char *name, wimp_w *handle, wimp_box *size);
- static void sv_win_event_handler(wimp_eventstr *e, void *handle);
- static void redraw_window(wimp_w handle, sv_windata *wd);
- static os_error *draw_window(sv_windata *wd, wimp_box to_do);
- static void toggle_window(wimp_w handle, BOOL *open);
- static os_error *draw_horiz_compass(void);
- static os_error *draw_vert_compass(void);
- static int x_h(REAL azimuth);
- static int y_h(REAL altitude);
- static void xy_v(REAL altitude, REAL azimuth, int *xptr, int *yptr);
- static void observer(void);
- static BOOL ob_raw_handler(dbox d, void *event, void *handle);
- static void data_to_box(observerstr data);
- static void data_from_box(observerstr *ptr);
- static void ob_ok_click(void);
- static BOOL save_ob_data(void);
- static BOOL load_ob_data(void);
- static void ob_arrows(int response, int *targptr);
- static void load_sys_date(void);
- static void sv_Draw_circle(int radius);
- static void sv_Draw_move(int x, int y);
- static void sv_Draw_line(int x, int y);
- static void sv_Draw_bezi(int x1, int y1, int x2, int y2, int x3, int y3);
- static void sv_Draw_endp(void);
- static BOOL register_module(initfntype *initfn);
- static BOOL install_select_entry(modulestr new_module);
- static BOOL install_display_entry(modulestr new_module);
- static void invoke_displayfns(char *hit);
- static void display_rebuild(void);
- static void recalc_horiz_xy(void);
- static void recalc_vert_xy(void);
- static void window_click(int x, int y, wimp_w wh, sv_windata *wd);
- static void cutup(char *linestart[]);
- static void infobox_load(int objno);
- static void infobox_buttons(int nobjects);
- static void build_lists(void);
- static void invoke_selectfns(char *hit);
- static void fillin_obfields(observerstr *ptr);
- static void invalidate_framearea(wimp_w whandle, sv_windata wdat);
- static void establish_new_frame(wimp_w whandle, sv_windata *wd);
- static void calculate_frame(sv_windata *wd);
- static void establish_new_selection(int new_owner);
- static void invalidate_all(void);
- static void cancel_selection(void);
- static void sel_info(void);
- static void build_timestring(char *stringptr, BOOL valid, int hour, int min);
- static int nearest_dir(REAL azim);
- static void arrange_windows(REAL alt, REAL az);
- static void arrange_horiz(REAL alt, REAL az);
- static void arrange_vert(REAL alt, REAL az);
- static void print_sub_menuproc(char *hit);
- static BOOL pdriver_installed(void);
- static void print_hquadrant(void);
- static void print_vertical(void);
- static BOOL overlap(wimp_box *b1, wimp_box *b2, wimp_box *olap);
- static void build_horiz_title(char *title, BOOL font_ok);
- static void build_vert_title(char *title, BOOL font_ok);
- static os_error *write_horiz_title(char *title, BOOL font_ok);
- static os_error *write_vert_title(char *title, BOOL font_ok);
- static os_error *write_title(int x, int y, char *title, BOOL font_ok);
- static void ob_info_string(char *title, BOOL split, BOOL font_ok);
- static os_error *write_string(char *title, int *countptr);
- static void print_window(sv_windata *wd, int title_ht);
- static os_error *sprite_tables(void);
- static os_error *save_error(os_error *ptr1, os_error *ptr2);
-
-
- /********************************************************/
- /* GLOBAL VARIABLES */
- /********************************************************/
-
- /*------------------------------------------------------*/
- /* Program environment */
- /*------------------------------------------------------*/
- char app_dir[256]; /* For SkyView$Dir. */
- static char start_file[256]=""; /* For cmd line file. */
- static char data_file[256]; /* For name of file of */
- /* observer defaults. */
-
- /*------------------------------------------------------*/
- /* Information on the Modules */
- /*------------------------------------------------------*/
- static int module_count = 0; /* No. of Modules */
- /* registered. */
- static int select_count = 0; /* No. of non-null object- */
- /* selecting fns registered*/
- static int display_count = 0;/* No. of non-null display */
- /* functions (fns to set */
- /* display options) */
- /* registered. */
- #define MAXMODULES 32
-
- /* Set up an array to record which modules are enabled */
- /* and which disabled. */
- static BOOL enabled[MAXMODULES];
-
- /* Set up an array of fnliststrs, to record a list of */
- /* functions for each module. */
- static fnliststr module_fns[MAXMODULES];
-
- /* Set up an index array which defines which module */
- /* owns the nth entry in the Select menu. */
- static int sel_index[MAXMODULES];
-
- /* Set up an index array which defines which module */
- /* owns the nth entry in the Display menu. */
- static int disp_index[MAXMODULES];
-
- /* Set up an index array which defines which entry in */
- /* the Select menu is owned by module n. */
- static int module_index[MAXMODULES];
-
- /*------------------------------------------------------*/
- /* Character arrays etc for receiving info from Modules */
- /*------------------------------------------------------*/
- #define MAXRQ 5 /*Max no. of simultaneous info requests.*/
- static char infobuf[MAXRQ*MAXINFO];
- char *infoptr = infobuf;
-
- /*------------------------------------------------------*/
- /* Menu Variables */
- /*------------------------------------------------------*/
- static menu main_menu; /* Top of menu tree */
- static menu display_sub_menu;/* Sub-menu for 'Display' */
- static menu sel_sub_menu; /* Sub-menu for 'Sel obj.' */
- static menu view_sub_menu; /* Sub-menu for 'View sel.'*/
- static menu print_sub_menu; /* Sub-menu for 'Print' */
-
- char *module_submenu_hits = NULL; /* For hits on */
- /* module sub-menus. */
-
- /*------------------------------------------------------*/
- /* Flag causing Select or Disp fns to be called repeat- */
- /* edly. Used when module has a dbox which is per- */
- /* sisting (user has clicked OK with Adjust). */
- /*------------------------------------------------------*/
- BOOL dbox_persisting = FALSE;
-
- /*------------------------------------------------------*/
- /* Flag causing plotting lists to be rebuilt following */
- /* a call to a Display function. Set by the module in */
- /* question if the Display options have been so drastic-*/
- /* ally modified (eg change of position) that a simple */
- /* re-drawing of the windows will not do. */
- /*------------------------------------------------------*/
- BOOL rebuild_request = FALSE;
-
- /*------------------------------------------------------*/
- /* Window Variables */
- /*------------------------------------------------------*/
- static wimp_w horiz_handle; /* Handle for Horiz window */
- static sv_windata horiz_data;/* Data for Horiz window */
- static wimp_box horiz_size; /* Dimens. of Horiz window */
-
- static wimp_w vert_handle; /* Handle for Vert window */
- static sv_windata vert_data; /* Data for Vert window */
- static wimp_box vert_size; /* Dimens. of Vert window */
-
- /*------------------------------------------------------*/
- /* Screen Data */
- /*------------------------------------------------------*/
- static int width; /* Width of horiz window, */
- /* OS units. */
- static int height; /* Height of horiz window. */
- static REAL factor; /* Scaling factor in plott-*/
- /* ing functions. */
- static REAL compass_alt \
- =(REAL)59.5 * CONV; /* 'Altitude' of compass */
- /* circle in Vert window. */
- static REAL alt_max; /* Maximum altitude */
- /* in Horiz window. */
- static REAL alt_min; /* Min altitude */
- /* in Vert window. */
- static wimp_box targ = \
- {-8, -8, 8, 8}; /* Target for mouse clicks */
- /* on objects in windows. */
-
- /*------------------------------------------------------*/
- /* Palette and Printing Data */
- /*------------------------------------------------------*/
- static BOOL printing = FALSE; /* TRUE if currently */
- /* printing (via driver). */
-
- /* Set up a palette describing the standard Wimp colours*/
- static wimp_paletteword screen_palette[16] =
- {
- {0x00, 0xFF, 0xFF, 0xFF},
- {0x00, 0xDD, 0xDD, 0xDD},
- {0x00, 0xBB, 0xBB, 0xBB},
- {0x00, 0x99, 0x99, 0x99},
- {0x00, 0x77, 0x77, 0x77},
- {0x00, 0x55, 0x55, 0x55},
- {0x00, 0x33, 0x33, 0x33},
- {0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x44, 0x99},
- {0x00, 0xEE, 0xEE, 0x00},
- {0x00, 0x00, 0xCC, 0x00},
- {0x00, 0xDD, 0x00, 0x00},
- {0x00, 0xEE, 0xEE, 0xBB},
- {0x00, 0x55, 0x88, 0x00},
- {0x00, 0xFF, 0xBB, 0x00},
- {0x00, 0x00, 0xBB, 0xFF}
- };
-
- /* Set up a palette which is the same as the standard */
- /* Wimp palette, but which has an inverted grey scale. */
- static wimp_paletteword printer_palette[16] =
- {
- {0x00, 0x00, 0x00, 0x00},
- {0x00, 0x33, 0x33, 0x33},
- {0x00, 0x55, 0x55, 0x55},
- {0x00, 0x77, 0x77, 0x77},
- {0x00, 0x99, 0x99, 0x99},
- {0x00, 0xBB, 0xBB, 0xBB},
- {0x00, 0xDD, 0xDD, 0xDD},
- {0x00, 0xFF, 0xFF, 0xFF},
- {0x00, 0x00, 0x44, 0x99},
- {0x00, 0xEE, 0xEE, 0x00},
- {0x00, 0x00, 0xCC, 0x00},
- {0x00, 0xDD, 0x00, 0x00},
- {0x00, 0xEE, 0xEE, 0xBB},
- {0x00, 0x55, 0x88, 0x00},
- {0x00, 0xFF, 0xBB, 0x00},
- {0x00, 0x00, 0xBB, 0xFF}
- };
-
- /* Declare pixel translation tables for sprite plotting.*/
- static sprite_pixtrans sc_pixtrans[256]; /* For screen. */
- static sprite_pixtrans pr_pixtrans[256]; /* For printer.*/
-
- /* Declare 'sprite factor' tables for sprite plotting. */
- static sprite_factors s_factors20; /*For mode 20 sprites*/
- static sprite_factors s_factors12; /*For mode 12 sprites*/
-
- /* Define some constants for functions which build title*/
- #define TITLE_LEN 256
- #define THREE_LINES TRUE
- #define ONE_LINE FALSE
-
- /* Define overall scaling factor for printing. */
- #define SCALFACT (5<<14)
-
- /* Define some constants for control of Font used to */
- /* print title strings. */
- #define TITLE_FONT "Homerton.Medium"
- #define PAL_BLACK 0x00000000
- #define PAL_WHITE 0xFFFFFF00
- #define FONT_SIZE ((1<<10)/5)
- #define VSHIFT 28
-
- /*------------------------------------------------------*/
- /* Plotting Lists for Windows */
- /*------------------------------------------------------*/
- #define MAXOBJS 600
- static plotobj horiz_list[MAXOBJS];
- static plotobj vert_list[MAXOBJS];
-
- /*------------------------------------------------------*/
- /* Compass-Drawing Data */
- /*------------------------------------------------------*/
- #define NDIR 8 /* No. of directions of view offered */
- /* to user, and number of compass */
- /* labels in Horiz and Vert windows. */
-
- /* Array giving the NDIR azimuthal offsets corresponding*/
- /* to the "directions of view" offered to the user, and */
- /* (equivalently) the positions of the compass labels. */
-
- static REAL direction[] = {
- (REAL)( 0.0)*CONV,
- (REAL)( 45.0)*CONV,
- (REAL)( 90.0)*CONV,
- (REAL)(135.0)*CONV,
- (REAL)(180.0)*CONV,
- (REAL)(225.0)*CONV,
- (REAL)(270.0)*CONV,
- (REAL)(315.0)*CONV};
-
-
- /* Array giving the NDIR compass labels to be used by */
- /* the compass-drawing functions. */
-
- static c_label compass[] = {
- {0, "N" },
- {1, "NE"},
- {0, "E" },
- {1, "SE"},
- {0, "S" },
- {1, "SW"},
- {0, "W" },
- {1, "NW"}
- };
-
-
- /*------------------------------------------------------*/
- /* Variables & constants for invoking Draw Module in */
- /* Vert window. */
- /*------------------------------------------------------*/
-
- #define sv_XDraw_ProcessPath 0x60700
- #define sv_XDraw_StrokePath 0x60706
- #define sv_XDraw_Stroke 0x60704
- #define DrawU 100
- #define PathMax 254
- #define OutPMax 2048
-
- /* Set up Draw's transformation matrix so that 1 'user */
- /* unit' is 1/DrawU OS unit. */
- /* For now, assume DrawU = 100 */
- static int matrix[6] = {0x28F5C, 0, 0, 0x28F5C, 0, 0};
-
- /* Set butt caps and round joins. */
- static int cj_style = 1;
-
- /* Reserve space for Draw Paths. Set up path pointer. */
- static int path[PathMax+2];
- static int pathptr = 0;
- static int semi[OutPMax]= {0,OutPMax*4 - 8};
- /* Fill in No. of free bytes. */
-
- /* 'Register Set' structures for use with Draw SWIs. */
- static os_regset draw_regsS;
- static os_regset draw_regsP;
-
-
- /*------------------------------------------------------*/
- /* Variables relating to Selected Object */
- /*------------------------------------------------------*/
-
- selectstr selection;
- static BOOL selection_exists = FALSE;
- static int sel_owner; /* Module number of current owner */
- /* of selection. */
-
- /*------------------------------------------------------*/
- /* Variables relating to Observer Details */
- /*------------------------------------------------------*/
-
- static dbox d_ob; /* dbox for Observer Details. */
- static wimp_w ob_handle; /* handle for Observer Box. */
-
- static BOOL observer_verified = FALSE; /* Flag denoting*/
- /* whether user has verified the observer details. */
-
- /* Set 'factory defaults' for Observer Details */
- observerstr ob_data = {
- 517, /* Latitude *10 */
- TRUE, /* North */
- (REAL)0.902335, /* Latitude */
- 13, /* Longitude*10 */
- TRUE, /* West */
- (REAL)0.0226893, /* Longitude */
- 1, /* Day */
- 6, /* Month */
- 1992, /* Year */
- 0, /* Hour */
- 0, /* Minutes */
- 0.0f, /* Offset */
- 33754.5, /* Julian */
- (REAL)4.33582, /* Loc Siderial */
- 0, /* View North */
- (REAL)0.0, /* Radians */
- };
-
- /* Set up named constants for the field numbers in the */
- /* Observer Details dbox. */
- enum {
- ob_close_rq =-1, /* Result of cancelling dbox. */
- ob_ok_butt = 0, /* Icon No. of OK button. */
- ob_cancel_butt = 9, /* Icon No. of Cancel button. */
- set_butt =10, /* Icon No. of Set button. */
- sys_date_butt =12, /* Icon No. of Sys Time button.*/
- show_butt =70, /* Icon No. of Show button. */
- cent_butt = 30, /* Icon No. of century button. */
- e_or_w = 55, /* Icon No. of E or W display. */
- ew_butt = 56, /* Icon No. of E/W button. */
- n_or_s = 66, /* Icon No. of N or S display. */
- ns_butt = 67, /* Icon No. of N/S button. */
- dayf = 13, day_tu=14, day_td, day_uu, day_ud, /* Day */
- monf = 19, mon_tu=21, mon_td, mon_uu, mon_ud, /* Month */
- yrf = 25, yr_tu=26, yr_td, yr_uu, yr_ud, /* Year */
- hrf = 31, hr_tu=32, hr_td, hr_uu, hr_ud, /* Hour */
- minf = 37, min_tu=38, min_td, min_uu, min_ud, /* Minute */
- /* Longitude, Integer Part: */
- loif = 44, loi_hu=47, loi_hd, loi_tu, loi_td, loi_uu, loi_ud,
- /* Longitude, Decimal Part: */
- lodf = 46, lod_uu=53, lod_ud,
- ewf = 55, /* E or W */
- /* Latitude, Integer Part: */
- laif = 57, lai_tu=60, lai_td, lai_uu, lai_ud,
- /* Latitude, Decimal Part: */
- ladf = 59, lad_uu=64, lad_ud,
- nsf = 66, /* N or S */
- /* Time offset: */
- offf = 74, off_uu=75, off_ud, off_xu, off_xd};
-
- /* Increments corresponding to the arrow buttons: */
- static int addon[6] = {-1, 1, -10, 10, -100, 100};
-
- /* Special increments for Time Offset field: */
- static float offset_incr[4] = {-0.5f, 0.5f, -1.0f, 1.0f};
-
- /* Days in each month, for non-leap and leap years: */
- static int daysin[2][13] = {
- {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
- {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
- };
-
- /*------------------------------------------------------*/
- /* Variables & Constants relating to Info Box */
- /*------------------------------------------------------*/
- static dbox d_info;
- enum {
- info_cancel =-1, /* Response cancelling the dbox. */
- info_ok = 0, /* OK button. */
- info_select, /* Select button. */
- alt_field = 4, /* Altitude of object. */
- azim_field, /* Azimuth of object. */
- info_uparrow, /* Butt. to display next object. */
- info_objno, /* Display of object's number. */
- info_dnarrow, /* Butt. to display prev object. */
- info_textline /* First line of text. */
- };
-
- /* For info on objects which have been clicked on. */
- static int info_id[MAXRQ];
- static int info_modno[MAXRQ];
- static selectfntype *sel_fn_ptr[MAXRQ];
- static char *info_lineptr[MAXRQ][INFOBOX_LINES];
- static REAL info_alt[MAXRQ];
- static REAL info_azim[MAXRQ];
-
- /*------------------------------------------------------*/
- /* Constants realting to Selection Info Box */
- /*------------------------------------------------------*/
- enum {
- selinfo_cancel = -1, /* Response cancelling the dbox. */
- selinfo_ok, /* OK button. */
- selinfo_rise, /* Field for time of rising. */
- selinfo_set, /* Field for time of setting. */
- selinfo_culmin, /* Field for time of culminating.*/
- selinfo_textline /* First line of text. */
- };
-
-
- /********************************************************/
- /* Generic Window-Handling Functions */
- /********************************************************/
-
- /*------------------------------------------------------*/
- /* Create a window, yielding its handle. */
- /* Return TRUE if OK */
- /*------------------------------------------------------*/
-
- static BOOL create_window(char *name, wimp_w *handle, wimp_box *size)
- {
- wimp_wind *window; /* pointer to window definition */
- os_error *creation_error;
-
- window = template_syshandle(name); /* find template */
- if (window == 0)
- return FALSE;
-
- /* create window, handling any errors */
- creation_error=wimpt_complain(wimp_create_wind(window, handle));
- if (creation_error != 0)
- return FALSE;
-
- /* Make a note of the dimensions of the window. */
- *size = window->ex;
-
- return TRUE;
- }
-
- /*------------------------------------------------------*/
- /* Event Handler for a window */
- /*------------------------------------------------------*/
-
- static void sv_win_event_handler(wimp_eventstr *e, void *handle)
- /* handle points to a data block for the window */
- {
- sv_windata *windata = handle;
-
- switch (e->e)
- {
- case wimp_EREDRAW:
- /* Register current screen mode. Re-calculate */
- /* sprite-plotting tables if mode has changed. */
- if (wimpt_checkmode()) wimpt_noerr(sprite_tables());
- /* Draw requested part of requested window. */
- redraw_window(e->data.o.w, windata);
- break;
-
- case wimp_EOPEN:
- wimpt_noerr(wimp_open_wind(&e->data.o));
- break;
-
- case wimp_ECLOSE:
- wimpt_noerr(wimp_close_wind(e->data.o.w));
- windata->open = FALSE;
- break;
-
- case wimp_EBUT:
- {
- int x = e->data.but.m.x; /* Coordinates of */
- int y = e->data.but.m.y; /* mouse click. */
- wimp_w wh = e->data.but.m.w;/* Window handle. */
- window_click(x, y, wh, windata);
- break;
- }
-
- default:
- break;
- }
- return;
- }
-
- /*------------------------------------------------------*/
- /* Handler for mouse click inside window */
- /*------------------------------------------------------*/
- static void window_click(int x, int y, wimp_w wh, sv_windata *wd)
- {
- wimp_wstate result; /*Data on window. */
- coords_cvtstr conv; /*For doing conversions.*/
- coords_pointstr pt; /*For mouse coordinates.*/
- wimp_box work_targ; /*Target for clicks, in */
- /*work area coords. */
- infofntype *infofn; /*Ptr to info function. */
-
- plotobj *pstart=wd->listptr; /*Point to start of list*/
- plotobj *pend =pstart + wd->number; /* Point to end. */
- plotobj *p;
-
- int hits = 0;
-
- /* Obtain data to convert between screen coords and */
- /* window workspace coords. */
- wimpt_noerr(wimp_get_wind_state(wh, &result));
-
- /* Fill in the coords_cvtstr required by conversion */
- /* functions. */
- conv.box = result.o.box;
- conv.scx = result.o.x;
- conv.scy = result.o.y;
-
- /* Fill in the coords_pointstr with the screen coords of*/
- /* the mouse click. */
- pt.x = x;
- pt.y = y;
-
- /* Convert to work area coords. */
- coords_point_toworkarea(&pt, &conv);
-
- /* Search for hits with mouse on plotting objects. */
- /* Ignore objects whose parent module is currently */
- /* disabled, or whose parent module has no info fn. */
- /* Max No. of 'hits' is MAXRQ. */
-
- for(p = pstart; p<pend && hits<MAXRQ; p++)
- {
- /* Set up target for this object. */
- coords_offsetbox(&targ, p->wind_x, p->wind_y, &work_targ);
- /* Test for a hit. */
- if (coords_withinbox(&pt, &work_targ) &&\
- enabled[p->module] &&\
- (infofn = module_fns[p->module].infofn, infofn != NULL))
- {
-
- /* Point to place to write info string. */
- infoptr = infobuf + hits*MAXINFO;
-
- /* Get info from module. */
- infofn(p->id);
-
- /* Cut info string up into INFOBOX_LINES lines. */
- cutup(info_lineptr[hits]);
-
- /* Store data on object. Increment hits at end. */
- sel_fn_ptr[hits] = \
- module_fns[p->module].selectfn; /* Ptr to sel fn.*/
- info_modno[hits]= p->module;/* Module number. */
- info_id[hits] = p->id; /* Object's id. */
- info_alt[hits] = p->alt; /* Altitude. */
- info_azim[hits] = p->azim; /* Azimuth. */
- hits++;
- }
- }
-
- if (hits==0) return;
-
- /* Load info dbox with details of last object. */
- infobox_load(hits-1);
-
- /* Fade out up and down arrows if there is only 1 object*/
- if (hits==1)
- {
- dbox_fadefield(d_info, info_uparrow);
- dbox_fadefield(d_info, info_dnarrow);
- }
- else
- {
- dbox_unfadefield(d_info, info_uparrow);
- dbox_unfadefield(d_info, info_dnarrow);
- }
-
-
- /* Display dbox. */
- dbox_show(d_info);
-
- /* Deal with clicks on its buttons, changing between */
- /* 'hits' different objects as requested by user. */
- infobox_buttons(hits);
-
- /* Remove dbox from screen. */
- dbox_hide(d_info);
-
- return;
- }
-
-
- static void cutup(char *linestart[])
- /* Divide the contents of the info buffer into */
- /* INFOBOX_LINES separate lines. */
- /* Write pointers to the start of each line into the */
- /* pointer array linestart. */
- {
- int i;
- char *startptr;
-
- /* Make sure there is an end-of-string marker in the */
- /* buffer. */
- *(infoptr+MAXINFO-1) = '\0';
-
- /* First line always starts at start of buffer. */
- linestart[0] = infoptr;
-
- /* Look for the remaining INFOBOX_LINES - 1 lines. */
- for (i=1; i<INFOBOX_LINES; i++)
- {
- /* Look for end-of-line marker. */
- startptr = strchr(linestart[i-1],'\n');
- if (startptr != NULL)
- /* If found, change it to end-of-string, and point*/
- /* to start of next line. */
- *startptr++ = '\0';
- else
- /* If not found, point to end-of-string marker. */
- startptr = linestart[i-1] + strlen(linestart[i-1]);
- linestart[i] = startptr;
- }
-
- return;
- }
-
-
- static void infobox_load(int objno)
- {
- /* Load details of object objno into info dbox. */
-
- int i;
- REAL degrees;
- char numbuf[32];
-
- /* Fade Select button if object cannot be selected. */
- if (sel_fn_ptr[objno]==NULL)
- dbox_fadefield(d_info, info_select);
- else
- dbox_unfadefield(d_info, info_select);
-
- /* Altitude field. */
- degrees = info_alt[objno]/CONV;
- sprintf(numbuf, "%+5.1f°", (double)degrees);
- dbox_setfield(d_info, alt_field, numbuf);
-
- /* Azimuth field. */
- degrees = info_azim[objno]/CONV;
- sprintf(numbuf, "%5.1f°", (double)degrees);
- dbox_setfield(d_info, azim_field, numbuf);
-
- /* Object number. */
- sprintf(numbuf, "Object %i", objno+1);
- dbox_setfield(d_info, info_objno, numbuf);
-
- /* Write INFOBOX_LINES lines of text. */
- for (i=0; i < INFOBOX_LINES; i++)
- dbox_setfield(d_info, info_textline+i, info_lineptr[objno][i]);
-
- return;
- }
-
-
- static void infobox_buttons(int nobjects)
- {
- /* Deal with clicks on buttons in info box. Change */
- /* back and forth amongst the nobjects objects as */
- /* requested by the user. */
- /* The object initially showing is number nobjects-1. */
-
- int obj = nobjects-1; /* No. of object showing initially*/
- int response; /* Latest field clicked by user. */
- BOOL keep_open; /* TRUE if dbox to remain open after */
- /* this button is processed. */
-
- /* Loop until dbox is to close. */
- do
- {
-
- /* Get field number of latest click. */
- response = dbox_fillin(d_info);
-
- /* Take appropriate action. */
- switch (response) {
-
- case info_cancel:
- /* Dbox cancelled. Just close it. */
- keep_open = FALSE;
- break;
-
- case info_ok:
- /* Finished with dbox. */
- keep_open = dbox_persist();
- break;
-
- case info_select:
- /* Select the object whose details are currently */
- /* on display. */
- /* Set id field of 'selection' to specify which */
- /* object is meant. */
- selection.id = info_id[obj];
- /* Call appropriate Select function to fill in */
- /* the remaining fields. */
- module_fns[info_modno[obj]].selectfn(window_selection);
- /* Establish the new selection. */
- establish_new_selection(info_modno[obj]);
- keep_open = dbox_persist();
- break;
-
- case info_uparrow:
- /* Display info on next object. */
- obj = (obj+1)%nobjects;
- infobox_load(obj);
- keep_open = TRUE;
- break;
-
- case info_dnarrow:
- /* Display info on previous object. */
- obj = (obj+nobjects-1)%nobjects;
- infobox_load(obj);
- keep_open = TRUE;
- break;
-
- default:
- /* Unknown response. Do nothing. */
- keep_open = TRUE;
- break;
-
- }
-
- } while (keep_open);
-
- return;
- }
-
-
- /*------------------------------------------------------*/
- /* Re-draw a window */
- /*------------------------------------------------------*/
-
- static void redraw_window(wimp_w handle, sv_windata *wd)
- {
- int more, x_orig, y_orig;
- wimp_redrawstr r;
- wimp_box to_redraw;
-
- r.w = handle;
- wimpt_noerr(wimp_redraw_wind(&r, &more));
- /* Work out screen coords of work area origin. */
- x_orig = r.box.x0 - r.scx;
- y_orig = r.box.y1 - r.scy;
-
- while (more)
- {
- /* Move graphics origin to coincide with work */
- /* area origin. */
- bbc_origin(x_orig,y_orig);
-
- /* Get work area coords of rectangle to re-draw */
- coords_offsetbox(&r.g, -x_orig, -y_orig, &to_redraw);
-
- /* Draw requested part of window. */
- wimpt_noerr(draw_window(wd, to_redraw));
-
- /* Move graphics origin back again */
- bbc_origin(0,0);
-
- /* Get next rectangle to do. */
- wimpt_noerr(wimp_get_rectangle(&r, &more));
- }
-
- return;
- }
-
-
- /*------------------------------------------------------*/
- /* Function to plot (or print) the specified part of a */
- /* window. */
- /*------------------------------------------------------*/
- static os_error *draw_window(sv_windata *wd, wimp_box to_do)
- {
- os_error *errptr;
- plotobj *p;
- plotobj *pstart = wd->listptr; /*Start of plot list. */
- plotobj *pend = pstart + wd->number; /*End of list. */
-
- /*......................................................*/
- /* Plot the objects in the plotting list. */
- /*......................................................*/
-
- /* Only plot those whose bounding box overlaps the */
- /* rectangle to be drawn. */
- /* Do not plot if parent module is currently disabled. */
-
- for(p = pstart; p < pend; p++)
- if (coords_boxesoverlap(&to_do, &p->bounds) &&\
- enabled[p->module])
- {
- errptr = p->plotfn(p->wind_x, p->wind_y, p->id);
- if (errptr != NULL) return errptr;
- }
- /*......................................................*/
-
- /* Also do the following, without bothering to check */
- /* whether the requested rectangle includes them: */
-
- /* Draw frame around selected object, if it exists */
- /* and is currently in window. */
- if (selection_exists && wd->selnum != NOWHERE)
- {
- /* Get x and y coords of selected object. */
- int sel_x = (pstart + wd->selnum)->wind_x;
- int sel_y = (pstart + wd->selnum)->wind_y;
- /* Set foreground graphics colour to Wimp colour 0 */
- errptr = sv_setcolour(0);
- if (errptr != NULL) return errptr;
- /* Draw frame, after shifting it to coords of */
- /* selected object. */
- errptr = bbc_rectangle(\
- wd->sel_frame.x + sel_x, wd->sel_frame.y + sel_y,\
- wd->sel_frame.w, wd->sel_frame.h);
- if (errptr != NULL) return errptr;
- }
-
- /* Call fn to re-draw compass points, and return. */
- return (wd->compass_drawfn)();
-
- }
-
-
- /*------------------------------------------------------*/
- /* Toggle state of window between open and closed. */
- /* Update Open/Closed flag appropriately. */
- /*------------------------------------------------------*/
-
- static void toggle_window(wimp_w handle, BOOL *open)
- {
- if (*open)
- /* Close the window */
- {
- wimpt_noerr(wimp_close_wind(handle));
- *open = FALSE;
- }
- else
- {
- /* Get window state */
- wimp_wstate state;
- if (wimpt_complain(wimp_get_wind_state(handle, &state)) == 0)
- {
- /* Open the window, in front of all others */
- state.o.behind = -1;
- wimpt_noerr(wimp_open_wind(&state.o));
- *open = TRUE;
- }
- }
- }
-
-
-
- /********************************************************/
- /* Specific Window-handling Functions */
- /********************************************************/
-
- /*------------------------------------------------------*/
- /* Draw compass points for Horiz window */
- /*------------------------------------------------------*/
-
- static os_error *draw_horiz_compass(void)
- {
- static int bar_y0 = -4; /* Min y coord of horiz bar. */
- static int bar_wd = 3; /* "Width" of horiz bar. */
-
- static int tik_y0 =-12; /* Min y coord of tick mark. */
- static int tik_ht = 7; /* "Height" of tick mark. */
- static int tik_os = -1; /* x offset of LHS of tick mk */
- static int tik_wd = 2; /* "Width" of tick mark. */
-
- static int lab_dn =-14; /* Down shift to print label */
- static int lab_lt = -8; /* Fixed left shift before */
- /* printing label */
- static int chr_sh = 8; /* Left shift for each */
- /* additional label character */
-
- int i; /* Counter for drawing compass point labels*/
- int x_pos; /* Horizontal position of compass ticks. */
- char *ptr; /* Pointer to text of compass label. */
- int left; /* Total left shift before printing label. */
-
- os_error *errptr;
-
-
- /* Set foreground graphics colour to Wimp colour 0 */
- errptr = sv_setcolour(0);
- if (errptr != NULL) return errptr;
-
- /* Draw a horizontal bar across whole window to denote */
- /* horizon. */
- errptr = bbc_rectanglefill(horiz_size.x0,bar_y0,width,bar_wd);
- if (errptr != NULL) return errptr;
-
- /* Draw in the NDIR compass point labels */
- for (i=0; i<NDIR; i+=1)
- {
- /* Position of tick mark. */
- x_pos = x_h(direction[i]);
-
- /* Calculate left shift. */
- left = lab_lt - compass[i].len * chr_sh;
-
- /* Draw tick mark. */
- errptr = bbc_rectanglefill(x_pos + tik_os, tik_y0, tik_wd, tik_ht);
- if (errptr != NULL) return errptr;
-
- /* Move to print position. */
- errptr = bbc_moveby(left, lab_dn);
- if (errptr != NULL) return errptr;
-
- /* Point to text of label, and print it one char */
- /* at a time. */
- for (ptr = compass[i].name; *ptr; ptr += 1)
- {errptr = bbc_vdu((int)*ptr);
- if (errptr != NULL) return errptr;}
-
- }
-
- return NULL;
- }
-
-
- /*------------------------------------------------------*/
- /* Draw compass points for Vert window. */
- /*------------------------------------------------------*/
-
- static os_error *draw_vert_compass(void)
- {
- int i;
- int x,y;
- int lab_dn =-12;
- int lab_lt = 8;
- int chr_sh = 8;
- int left;
- char *ptr;
-
- os_error *errptr;
-
- /* Set foreground graphics colour to Wimp colour 0 */
- errptr = sv_setcolour(0);
- if (errptr != NULL) return errptr;
-
- /* Plot the Draw Path set up earlier. */
- /* If plotting to screen, use the semi-digested form */
- /* for speed. */
- if (!printing)
- {
- draw_regsS.r[0] = (int)semi;
- errptr = os_swix(sv_XDraw_ProcessPath, &draw_regsS);
- }
- else
- /* If printing, process the 'raw' path to take full */
- /* advantage of the resolution of the printer. */
- {
- draw_regsP.r[0] = (int)path;
- errptr = os_swix(sv_XDraw_Stroke, &draw_regsP);
- }
- if (errptr != NULL) return errptr;
-
- /* Plot the NDIR compass labels. */
- for(i=0; i<NDIR; i++)
- {
- xy_v(compass_alt*(REAL)0.94, direction[i], &x, &y);
- y -= lab_dn;
- left = lab_lt + compass[i].len * chr_sh;
- x -= left;
-
- /* Move to print position. */
- errptr = bbc_move(x,y);
- if (errptr != NULL) return errptr;
-
- /* Point to text of label, and print it one char */
- /* at a time. */
- for (ptr = compass[i].name; *ptr; ptr += 1)
- {errptr = bbc_vdu((int)*ptr);
- if (errptr != NULL) return errptr;}
- }
-
- return NULL;
- }
-
- /********************************************************/
- /* Plotting Functions */
- /********************************************************/
-
- static int x_h(REAL azimuth)
- {
- /* - Horizontal window - */
- /* Calculate x-coordinate corresponding to given */
- /* azimuth, taking into account the current direction */
- /* of view. */
-
- int x;
- REAL x_floating = factor * (azimuth - ob_data.ang);
-
- x = (int)floor((double)x_floating);
- if (x < horiz_size.x0)
- x += width;
- else if (x >= horiz_size.x1)
- x -= width;
-
- return x;
- }
-
-
- static int y_h(REAL altitude)
- {
- /* - Horizontal window - */
- /* Calculate y-coordinate corresponding to given */
- /* altitude. */
-
- return (int)(factor*altitude);
- }
-
-
- static void xy_v(REAL altitude, REAL azimuth, int *xptr, int *yptr)
- {
- /* - Vert window - */
- /* Calculate x- and y-coordinate from given altitude */
- /* and azimuth, taking into account current direction */
- /* of view. */
-
- REAL theta = azimuth - ob_data.ang;
- REAL r = factor*(PIby2 - altitude);
-
- if (xptr != NULL)
- *xptr = (int)floor( (double)r * \
- sin((double)theta));
- if (yptr != NULL)
- *yptr = (int)floor(-(double)r * \
- cos((double)theta));
- return;
- }
-
-
- /*------------------------------------------------------*/
- /* Functions for constructing Draw Path */
- /*------------------------------------------------------*/
-
- static void sv_Draw_circle(int r)
- {
- int ar = (int)((REAL)0.55228475*(REAL)r);
-
- /* Move to (r,0). */
- sv_Draw_move(r,0);
-
- /* Set up four Bezier curves describing one quadrant each*/
- sv_Draw_bezi( r, ar, ar, r, 0, r);
- sv_Draw_bezi(-ar, r, -r, ar, -r, 0);
- sv_Draw_bezi( -r,-ar, -ar, -r, 0,-r);
- sv_Draw_bezi( ar, -r, r,-ar, r, 0);
-
- return;
- }
-
- static void sv_Draw_move(int x, int y)
- {
- if (pathptr+3 > PathMax) return;
- path[pathptr++] = 2;
- path[pathptr++] = x;
- path[pathptr++] = y;
-
- return;
- }
-
- static void sv_Draw_line(int x, int y)
- {
- if (pathptr+3 > PathMax) return;
- path[pathptr++] = 8;
- path[pathptr++] = x;
- path[pathptr++] = y;
-
- return;
- }
-
- static void sv_Draw_bezi(int x1, int y1, int x2, int y2, int x3, int y3)
- {
- if (pathptr+7 > PathMax) return;
- path[pathptr++] = 6;
- path[pathptr++] = x1;
- path[pathptr++] = y1;
- path[pathptr++] = x2;
- path[pathptr++] = y2;
- path[pathptr++] = x3;
- path[pathptr++] = y3;
-
- return;
- }
-
- static void sv_Draw_endp(void)
- {
- path[pathptr] = 0;
- path[pathptr+1] = 0;
-
- return;
- }
-
-
- /*------------------------------------------------------*/
- /* Function for setting graphics fore/back colour. */
- /*------------------------------------------------------*/
- os_error *sv_setcolour(int colour)
- {
-
- /* If not currently printing, pass colour unaltered to */
- /* Wimp_SetColour. */
- if (!printing) return wimp_setcolour(colour);
-
- /* If printing, use printer palette instead of screen */
- /* palette. */
- {
- /* Using a variable of type ctrans_type, split the */
- /* given argument into a Wimp colour number (0 - 15), */
- /* a GCOL action, and a Foreground / Background flag. */
- ctrans_type ctrans;
- wimp_paletteword entry;
- int w_colour;
- int fore_back;
- int gcol_act;
- int gcol_out;
-
- ctrans.argument = colour;
- w_colour = (int)ctrans.fields.w_colour;
- fore_back = (int)ctrans.fields.foreback << 7;
- gcol_act = (int)ctrans.fields.gcol_act;
-
- /* Get the printer palette entry corresponding to */
- /* w_colour. */
- entry = printer_palette[w_colour];
-
- /* Set the GCOL using the appropriate ColourTrans call*/
- return colourtran_setGCOL(entry, fore_back, gcol_act, &gcol_out);
-
- }
- }
-
- /*------------------------------------------------------*/
- /* Function to plot a Mode 12 or Mode 20 sprite, scaled */
- /* to suit the current screen mode. */
- /*------------------------------------------------------*/
- os_error *sv_plotsprite(sprite_id *id,
- BOOL mode20,
- int x, int y,
- int col, int row)
- {
- int gcol_act = 8; /*Plot with overwriting, using mask.*/
-
- /* Calculate plotting position in OS units which will */
- /* place the Key Pixel at the desired coords (x,y). */
- x -= col * 2;
- y -= row * (mode20? 2 : 4);
-
- /* The pixel translation table to use when plotting */
- /* depends on whether the output is going to the screen */
- /* or the printer. */
- /* Also, use scaling factors appropriate to sprite mode.*/
-
- return sprite_put_scaled(resspr_area(),
- id,
- gcol_act,
- x, y,
- (mode20? &s_factors20: &s_factors12),
- (printing? pr_pixtrans : sc_pixtrans));
- }
-
- /*------------------------------------------------------*/
- /* Function to re-calculate Sprite scaling and trans- */
- /* lation tables, following a change of screen mode. */
- /*------------------------------------------------------*/
- static os_error *sprite_tables(void)
- {
- /* Set scaling factors for a mode 12 sprite. */
- s_factors12.xmag = 2;
- s_factors12.ymag = 4;
- s_factors12.xdiv = wimpt_dx();
- s_factors12.ydiv = wimpt_dy();
-
- /* Set scaling factors for a mode 20 sprite. */
- s_factors20.xmag = 2;
- s_factors20.ymag = 2;
- s_factors20.xdiv = wimpt_dx();
- s_factors20.ydiv = wimpt_dy();
-
- /* Set pixel translation table for plotting to screen. */
- /* Use same table for mode 12 and mode 20 sprites. */
- return colourtran_select_table(20,
- screen_palette,
- -1,
- (wimp_paletteword *)(-1),
- sc_pixtrans);
- }
-
- /********************************************************/
- /* Main Menu Handling */
- /********************************************************/
-
- /*------------------------------------------------------*/
- /* pre menu proc */
- /*------------------------------------------------------*/
-
- static menu main_premenuproc(void *handle)
- {
- BOOL fade_select_item; /* TRUE if Select item needs */
- /* to be faded. */
-
- /* Fade Horiz and Vert items if observer details have */
- /* not been checked yet. */
- /* Tick them if the corresponding window is open now. */
- menu_setflags(main_menu, item_horiz, \
- horiz_data.open, !observer_verified);
- menu_setflags(main_menu, item_vert, \
- vert_data.open, !observer_verified);
-
- /* Fade Print item if observer details have not */
- /* been verified yet. */
- menu_setflags(main_menu, item_print, 0, !observer_verified);
-
- /* Fade Select item if observer details have not */
- /* been verified yet, or if there are no items in the */
- /* Select sub-menu. */
- fade_select_item = !observer_verified || (select_count == 0);
- menu_setflags(main_menu, item_select, 0, fade_select_item);
-
- /* Fade View item if ob. details not verified yet. */
- menu_setflags(main_menu, item_view, 0, !observer_verified);
-
- /* Fade Details and Cancel if there is no selection. */
- menu_setflags(main_menu, item_details, 0, !selection_exists);
- menu_setflags(main_menu, item_cancel, 0, !selection_exists);
-
- /* Fade 'View sel.' sub-menu items according to */
- /* whether or not there is a selection, and (if */
- /* there is) when it can be seen. */
- menu_setflags(view_sub_menu, view_item_now,\
- 0, !(selection_exists && selection.now));
- menu_setflags(view_sub_menu, view_item_rising,\
- 0, !(selection_exists && selection.rising));
- menu_setflags(view_sub_menu, view_item_setting,\
- 0, !(selection_exists && selection.setting));
- menu_setflags(view_sub_menu, view_item_culminating,\
- 0, !(selection_exists && selection.culminating));
-
- return main_menu;
- }
-
- /*------------------------------------------------------*/
- /* handle hits on main menu */
- /*------------------------------------------------------*/
-
- static void main_menuproc(void *handle, char *hit)
- {
- switch (hit[0])
- {
- case item_info:
- sv_info_about_program();
- break;
-
- case item_observer:
- /* Make sure menu has gone. It wouldn't */
- /* reflect changes made by the Observer dbox*/
- event_clear_current_menu();
- observer();
- break;
-
- case item_display:
- invoke_displayfns(hit);
- break;
-
- case item_horiz:
- /* Open window if it's closed, & vice versa */
- toggle_window(horiz_handle, &horiz_data.open);
- break;
-
- case item_vert:
- /* Open window if it's closed, & vice versa */
- toggle_window(vert_handle, &vert_data.open);
- break;
-
- case item_print:
- print_sub_menuproc(hit);
- break;
-
- case item_select:
- invoke_selectfns(hit);
- break;
-
- case item_view:
- view_sub_menuproc(hit);
- break;
-
- case item_details:
- sel_info();
- break;
-
- case item_cancel:
- cancel_selection();
- break;
-
- case item_quit:
- exit(0);
- break;
-
- default:
- break;
- }
-
- return;
- }
-
-
- /**** Functions dealing with printing of window data ****/
-
- /*------------------------------------------------------*/
- /* Function to handle hits on Print sub-menu */
- /*------------------------------------------------------*/
- static void print_sub_menuproc(char *hit)
- {
- switch (hit[1])
- {
- case print_item_horizq:
- /* Print a quadrant of the Horiz window. */
- if (!pdriver_installed()) return;
- printing = TRUE;
- print_hquadrant();
- printing = FALSE;
- break;
-
- case print_item_vertc:
- /* Print the Vert window. */
- if (!pdriver_installed()) return;
- printing = TRUE;
- print_vertical();
- printing = FALSE;
- break;
-
- default:
- /* Unknown option. Do nothing. */
- break;
-
- }
-
- return;
- }
-
- /* ********* Functions dealing with printing ********** */
-
- /*------------------------------------------------------*/
- /* Function to print a quadrant of the Horizontal */
- /* window (centered on the current direction of view). */
- /*------------------------------------------------------*/
- static void print_hquadrant(void)
- {
- int left_dir; /* Direction of view corresponding to */
- /* left side of window area. */
- int right_dir; /* Direction of view corresponding to */
- /* right side of window area. */
- int wider = 64; /* Amount to widen window area to make*/
- /* sure it includes a compass label at*/
- /* each side as well as in the middle.*/
-
- int title_ht = 64; /* Height of box containing title. */
-
- /* Specify the area of the window to be plotted: */
-
- /* Find the directions of view corresponding to */
- /* the left and right sides of the print region. */
- left_dir = (ob_data.dir + NDIR - 1) % NDIR;
- right_dir = (ob_data.dir + 1) % NDIR;
- /* Then specify the window area required. */
- horiz_data.wind_area.x0 = x_h(direction[left_dir]) - wider;
- horiz_data.wind_area.y0 = horiz_size.y0;
- horiz_data.wind_area.x1 = x_h(direction[right_dir]) + wider;
- horiz_data.wind_area.y1 = horiz_size.y1;
-
- /* Print the specified part of the window, with title */
- /* and frame. */
- print_window(&horiz_data, title_ht);
-
- return;
- }
-
- /*------------------------------------------------------*/
- /* Function to build a title string for the Horiz window*/
- /*------------------------------------------------------*/
- static void build_horiz_title(char *title, BOOL font_ok)
- {
- /* Write current observer details into a string. Put */
- /* everything onto a single line of text. */
- ob_info_string(title, ONE_LINE, font_ok);
- return;
- }
-
- /*------------------------------------------------------*/
- /* Function to write out the title for the Horiz window.*/
- /* Return any os_error which occurs. */
- /*------------------------------------------------------*/
- static os_error *write_horiz_title(char *title, BOOL font_ok)
- {
- int x, y;
-
- x = horiz_data.wind_area.x0 + 8;
- y = horiz_data.wind_area.y1 + 48;
- return write_title(x, y, title, font_ok);
- }
-
- /*------------------------------------------------------*/
- /* Function to print the entire Vertical window. */
- /*------------------------------------------------------*/
- static void print_vertical(void)
- {
- int title_ht = 160; /* Height of box containing title.*/
-
- /* Specify the window area required (= whole area). */
- vert_data.wind_area = vert_size;
-
- /* Print the specified part of the window, with title */
- /* and frame. */
- print_window(&vert_data, title_ht);
-
- return;
- }
-
- /*------------------------------------------------------*/
- /* Function to build a title string for the Vert window.*/
- /*------------------------------------------------------*/
- static void build_vert_title(char *title, BOOL font_ok)
- {
- /* Write current observer details into a string. Split */
- /* the info into three separate lines. */
- ob_info_string(title, THREE_LINES, font_ok);
- return;
- }
-
- /*------------------------------------------------------*/
- /* Function to write out the title for the Vert window. */
- /* Return any os_error which occurs. */
- /*------------------------------------------------------*/
- static os_error *write_vert_title(char *title, BOOL font_ok)
- {
- os_error *errptr;
- int x, y;
-
- x = vert_data.wind_area.x0 + 62;
- y = vert_data.wind_area.y1 + 144;
- errptr = write_title(x, y, title, font_ok);
- if (errptr != NULL) return errptr;
- title += strlen(title)+1;
-
- x = vert_data.wind_area.x0 + 62;
- y = vert_data.wind_area.y1 + 96;
- errptr = write_title(x, y, title, font_ok);
- if (errptr != NULL) return errptr;
- title += strlen(title)+1;
-
- x = vert_data.wind_area.x0 + 62;
- y = vert_data.wind_area.y1 + 48;
- return write_title(x, y, title, font_ok);
- }
-
- /*------------------------------------------------------*/
- /* Function to write out a title string, starting at */
- /* the specified coords (in OS units). Use anti- */
- /* aliassed font if BOOL flag is TRUE, system font */
- /* otherwise. */
- /*------------------------------------------------------*/
- static os_error *write_title(int x, int y, char *title, BOOL font_ok)
- {
- int counter;
- os_error *errptr;
-
- if (font_ok) return font_paint(title, font_OSCOORDS, x, y-VSHIFT);
-
- errptr = bbc_move(x,y);
- if (errptr != NULL) return errptr;
- return write_string(title, &counter);
- }
-
- /*------------------------------------------------------*/
- /* Function to print (part of) a window using RISC OS */
- /* printer drivers. */
- /*------------------------------------------------------*/
- static void print_window(sv_windata *wd, int title_ht)
- {
- os_regset OSFind_regs; /* For OS_Find call which */
- char file[] = "printer:"; /* opens "printer:" file. */
- int jhandle; /* Job handle. */
- int old; /* Old job handle. */
- int jdummy; /* For unwanted job handle.*/
-
- int frame_lt; /* Left of frame around window. */
- int frame_bt; /* Bottom of frame around window. */
- int frame_wd; /* Width of frame around window. */
- int frame_ht; /* Height of frame around window */
- /* (includes title box). */
- int margin = 4; /* All-round safety margin, to make*/
- /* sure complete image gets printed*/
-
- int bgcol = PAL_WHITE; /* Background colour (white). */
-
- print_box to_print;/* Region to be printed. Includes */
- /* window area, frame, title box & */
- /* all-round safety margin. */
-
- wimp_box to_draw; /* Region that PDriver */
- /* wants drawn. */
- int more; /* Pdriver's flag. */
- int id; /* ID of rectangle. */
- wimp_box clip; /* Pdriver's clip rectang.*/
-
- char title[TITLE_LEN]; /* Title string for windw.*/
- font font_handle; /* Font handle. */
- BOOL font_open = FALSE; /* Is a font file open? */
- wimp_paletteword foregr; /* Foreground pal. entry. */
- wimp_paletteword backgr; /* Background pal. entry. */
- int off = 0; /* Max intermediate colors*/
-
- /* Error pointer returned by RISC_OSLib routines: */
- os_error *errptr;
- /* Temp storage for errors during exit handling: */
- os_error *ptrsav_e = NULL; /* Pointer. */
- os_error err_blk_e; /* Error block. */
- /* Flag indicating if print job has started: */
- BOOL job_started = FALSE;
- /* Temp storage for errors which occur while printing: */
- os_error *ptrsav_p = NULL; /* Pointer. */
- os_error err_blk_p = { /* Error block (contain- */
- 255, /* ing a default message)*/
- "Error (print cancelled)"};
- /* Error block for unreported Escapes. */
- os_error unrep_esc = {
- 255,
- "Escape. (Print cancelled.)"};
-
-
- /* Open "printer:" file and record the returned handle. */
- OSFind_regs.r[0] = 0x8F;
- OSFind_regs.r[1] = (int)file;
- wimpt_noerr(os_find(&OSFind_regs));
- jhandle = OSFind_regs.r[0];
-
- /* Make sure returned handle is valid. */
- if (jhandle == 0)
- werr(FATAL, "Invalid 'printer:' handle");
-
- /* Turn on hourglass. */
- visdelay_begin();
-
- /* Start the print job. */
- errptr = print_selectjob(jhandle, "SkyViewPr", &old);
- if (errptr != NULL) goto error_exit;
- job_started = TRUE;
-
- /* Set pixel translation table for plotting sprites to */
- /* printer. Use same table for mode 12 sprites as for */
- /* mode 20 sprites. */
- errptr = colourtran_select_table(20,
- printer_palette,
- -1,
- (wimp_paletteword *)(-1),
- pr_pixtrans);
- if (errptr != NULL) goto error_exit;
-
- /* Open font for title string. If errors, use system */
- /* font instead. */
- errptr = font_find(TITLE_FONT, FONT_SIZE, FONT_SIZE, 0, 0, &font_handle);
- font_open = (errptr == NULL);
-
- /* Set anti-alias palette. */
- if (font_open)
- {
- foregr.word = PAL_BLACK;
- backgr.word = PAL_WHITE;
- errptr = colourtran_setfontcolours(&font_handle, &backgr, &foregr, &off);
- if (errptr != NULL) goto error_exit;
- }
-
- /* Call function to build title string. */
- wd->title_buildfn(title, font_open);
-
- /* Specify the rectangle to be plotted: */
-
- /* Using the given wind_area, work out the coords of */
- /* the frame surrounding the window and the title. */
- frame_lt = wd->wind_area.x0 - 1;
- frame_bt = wd->wind_area.y0 - 1;
- frame_wd = wd->wind_area.x1 - wd->wind_area.x0 + 1;
- frame_ht = wd->wind_area.y1 - wd->wind_area.y0 + 1 + title_ht;
- /* Can now fill in the printer_box. */
- to_print.x0 = frame_lt - margin;
- to_print.y0 = frame_bt - margin;
- to_print.x1 = frame_lt + frame_wd + margin;
- to_print.y1 = frame_bt + frame_ht + margin;
- /* Finally call PDriver_GiveRectangle. */
- /* Abort printing if there is an error. */
- errptr = print_giverectangle\
- (0, &to_print, &wd->matrix, &wd->posn, bgcol);
- if (errptr != NULL) goto error_exit;
-
- /* Get series of rectangles to be drawn. */
- errptr = print_drawpage(1, 0, NULL, (print_box *)&to_draw, &more, &id);
- if (errptr != NULL) goto error_exit;
-
- while (more != 0)
- {
-
- /* First do the following, without bothering to check */
- /* whether they are inside the requested rectangle: */
- /* Set foreground colour. */
- errptr = sv_setcolour(0);
- if (errptr != NULL) goto error_exit;
- /* Draw the frame around the window. */
- errptr = bbc_rectangle(frame_lt, frame_bt, frame_wd, frame_ht);
- if (errptr != NULL) goto error_exit;
- /* Draw a line to mark the top of the window. */
- errptr = bbc_move(frame_lt, wd->wind_area.y1);
- if (errptr != NULL) goto error_exit;
- errptr = bbc_draw(frame_lt+frame_wd, wd->wind_area.y1);
- if (errptr != NULL) goto error_exit;
- /* Clear 'escape seen' flag. */
- _kernel_escape_seen();
- /* Call function to write title. */
- errptr = wd->title_writefn(title, font_open);
- if (errptr != NULL) goto error_exit;
- /* Check for unreported escape. */
- if (_kernel_escape_seen()) { errptr = &unrep_esc;
- goto error_exit;}
-
- /* Then draw the window (if the requested rectangle */
- /* overlaps it at all), setting the pdriver's clip */
- /* rectangle so that nothing can spill over the frame.*/
- if (overlap(&to_draw, &wd->wind_area, &clip))
- {
- errptr = bbc_vdu(bbc_DefGraphWindow);
- if (errptr != NULL) goto error_exit;
- errptr = bbc_vduw(clip.x0);
- if (errptr != NULL) goto error_exit;
- errptr = bbc_vduw(clip.y0);
- if (errptr != NULL) goto error_exit;
- /* VDU clipping rectangle uses inclusive coords: */
- errptr = bbc_vduw(clip.x1-1);
- if (errptr != NULL) goto error_exit;
- errptr = bbc_vduw(clip.y1-1);
- if (errptr != NULL) goto error_exit;
- errptr = draw_window(wd, clip);
- if (errptr != NULL) goto error_exit;
- }
-
- /* Reset clipping rectangle. */
- errptr = bbc_vdu(bbc_DefaultWindow);
- if (errptr != NULL) goto error_exit;
-
- /* Get next rectangle. */
- errptr = print_getrectangle((print_box *)&to_draw, &more, &id);
- if (errptr != NULL) goto error_exit;
- }
-
- /* End the print job. */
- errptr = print_endjob(jhandle);
- if (errptr != NULL) goto error_exit;
-
- /* Normal exit: */
-
- /* Turn off hourglass. */
- visdelay_end();
- /* Re-select job which was active when this one started.*/
- errptr = print_selectjob(old, NULL, &jdummy);
- if (errptr != NULL) ptrsav_e = save_error(errptr, &err_blk_e);
- /* Close "printer:" file. */
- OSFind_regs.r[0] = 0;
- OSFind_regs.r[1] = jhandle;
- errptr = os_find(&OSFind_regs);
- if (errptr != NULL) ptrsav_e = save_error(errptr, &err_blk_e);
- /* Close font file. */
- if (font_open)
- {
- errptr = font_lose(font_handle);
- if (errptr != NULL) ptrsav_e = save_error(errptr, &err_blk_e);
- }
- /* If errors, report most recent, treating it as fatal. */
- wimpt_noerr(ptrsav_e);
-
- return;
-
-
- error_exit:
-
- /* Store the error for reporting later. If pointer is */
- /* obviously invalid, use the default message. */
- if ((int)errptr <= 0x1C)
- ptrsav_p = &err_blk_p;
- else
- ptrsav_p = save_error(errptr, &err_blk_p);
- /* Turn off hourglass. */
- visdelay_end();
- /* Cope with case where print job has started. */
- if (job_started)
- {
- /* Abort the print job. */
- errptr = print_abortjob(jhandle);
- if (errptr != NULL) ptrsav_e = save_error(errptr, &err_blk_e);
- /*Re-select job which was active when this one started*/
- errptr = print_selectjob(old, NULL, &jdummy);
- if (errptr != NULL) ptrsav_e = save_error(errptr, &err_blk_e);
- }
- /* Close "printer:" file. */
- OSFind_regs.r[0] = 0;
- OSFind_regs.r[1] = jhandle;
- errptr = os_find(&OSFind_regs);
- if (errptr != NULL) ptrsav_e = save_error(errptr, &err_blk_e);
- /* Close font file. */
- if (font_open)
- {
- errptr = font_lose(font_handle);
- if (errptr != NULL) ptrsav_e = save_error(errptr, &err_blk_e);
- }
- /* If errors occurred during error handling, report the */
- /* most recent, treating it as fatal. */
- wimpt_noerr(ptrsav_e);
- /* Report the original error. */
- wimpt_reporterror(ptrsav_p, wimp_EOK);
-
- return;
- }
-
- /*-------------------------------------------------------*/
- /* Function to save the error block pointed to by ptr1 */
- /* into the block pointed to by ptr2. Returns ptr2. */
- /*-------------------------------------------------------*/
- static os_error *save_error(os_error *ptr1, os_error *ptr2)
- {
- *ptr2 = *ptr1;
- return ptr2;
- }
-
- /*-------------------------------------------------------*/
- /* Function to build a string containing current observer*/
- /* details. Returns one string containing everything if */
- /* 'split' is FALSE, otherwise splits the info over 3 */
- /* strings which follow one after the other in memory. */
- /* Adds extra spaces if split is false and a fancy font */
- /* is being used. */
- /*-------------------------------------------------------*/
- static void ob_info_string(char *chrptr, BOOL split, BOOL font_ok)
- {
- chrptr += sprintf(chrptr, "SkyView");
- if (split)
- chrptr += sprintf(chrptr, "%c", '\0');
- else if (font_ok)
- chrptr += sprintf(chrptr, " ");
- else
- chrptr += sprintf(chrptr, " ");
- chrptr += sprintf(chrptr, "Lat. %.1f° ", (double)ob_data.lat10/10.0);
- chrptr += sprintf(chrptr, "%s, ", (ob_data.isn? "N" : "S"));
- chrptr += sprintf(chrptr, "Long. %.1f° ", (double)ob_data.long10/10.0);
- chrptr += sprintf(chrptr, "%s", (ob_data.isw? "W" : "E"));
- if (split)
- chrptr += sprintf(chrptr, "%c", '\0');
- else if (font_ok)
- chrptr += sprintf(chrptr, " ");
- else
- chrptr += sprintf(chrptr, " ");
- chrptr += sprintf(chrptr, "%02i/%02i/%i", ob_data.day, ob_data.month,
- ob_data.year);
- chrptr += sprintf(chrptr, " %02i:%02i", ob_data.hour, ob_data.min);
- if (ob_data.offset >= 0.0f)
- chrptr += sprintf(chrptr, " (GMT + ");
- else
- chrptr += sprintf(chrptr, " (GMT - ");
- chrptr += sprintf(chrptr, "%.1f h)", fabs((double)ob_data.offset));
- return;
- }
-
- /*-------------------------------------------------------*/
- /* Function to write out a string as a sequence of VDU */
- /* commands. Fills in *countptr with the number of */
- /* characters written, and returns any os_error which */
- /* occurred. */
- /*-------------------------------------------------------*/
- static os_error *write_string(char *chrptr, int *countptr)
- {
- os_error *errptr;
-
- errptr = sv_setcolour(0);
- if (errptr != NULL) return errptr;
-
- for (*countptr = 0; *chrptr; chrptr++, (*countptr)++)
- {errptr = bbc_vdu(*chrptr);
- if (errptr != NULL) return errptr;}
-
- return NULL;
- }
-
- /*------------------------------------------------------*/
- /* Function which sets the wimp_box *olap to the area */
- /* common to the wimp_boxes *b1 and *b2. Returns FALSE */
- /* and leaves *olap undefined if *b1 and *b2 do not */
- /* overlap. Returns TRUE if all OK. */
- /*------------------------------------------------------*/
- static BOOL overlap(wimp_box *b1, wimp_box *b2, wimp_box *olap)
- {
- os_error olap_error = { /* Define a new */
- 255, /* type of error. */
- "Invalid printer rectangle"};
-
- /* Check validity of *b1 and *b2. */
- if (b1->x0 > b1->x1 ||
- b1->y0 > b1->y1 ||
- b2->x0 > b2->x1 ||
- b2->y0 > b2->y1)
- {
- wimpt_reporterror(&olap_error, wimp_EOK);
- return FALSE;
- }
-
- /* Calculate overlap. */
- olap->x0 = (b1->x0 > b2->x0 ? b1->x0 : b2->x0);
- olap->x1 = (b1->x1 < b2->x1 ? b1->x1 : b2->x1);
- if (olap->x0 >= olap->x1) return FALSE;
-
- olap->y0 = (b1->y0 > b2->y0 ? b1->y0 : b2->y0);
- olap->y1 = (b1->y1 < b2->y1 ? b1->y1 : b2->y1);
- if (olap->y0 >= olap->y1) return FALSE;
-
- return TRUE;
- }
-
- /*------------------------------------------------------*/
- /* Function to check if a printer driver is installed */
- /*------------------------------------------------------*/
- static BOOL pdriver_installed(void)
- {
- /* Returns TRUE if a printer driver is installed. */
- /* Displays an error message and returns FALSE if no */
- /* printer driver is installed (or other error occurs). */
-
- os_error pdriver_error = { /* Define a new */
- 255, /* type of error. */
- "No printer driver installed"};
- os_error *errptr;
- print_infostr printerinfo;
-
- /* Attempt to get printer information from driver. */
- errptr = print_info(&printerinfo);
-
- /* All OK if no error. */
- if (errptr == NULL) return TRUE;
-
- /* If error is "No such SWI", PDriver is not installed. */
- if (errptr->errnum == 486)
- wimpt_reporterror(&pdriver_error, wimp_EOK);
- else
- wimpt_reporterror(errptr, wimp_EOK);
-
- return FALSE;
- }
-
-
- /**** Functions dealing with Selection of an Object *****/
-
- /*------------------------------------------------------*/
- /* Function to cancel selection. */
- /*------------------------------------------------------*/
- static void cancel_selection(void)
- {
- /* Remove frame around old selection (if one is */
- /* currently in window). */
- if (selection_exists)
- {
- if (horiz_data.selnum != NOWHERE)
- invalidate_framearea(horiz_handle, horiz_data);
- if (vert_data.selnum != NOWHERE)
- invalidate_framearea(vert_handle, vert_data);
- }
- /* Reset selection flag. */
- selection_exists = FALSE;
- /* Set owner number to invalid value. */
- sel_owner = NO_ONE;
-
- return;
- }
-
- /*------------------------------------------------------*/
- /* Function to display info on selected object. */
- /*------------------------------------------------------*/
- static void sel_info(void)
- {
- dbox d; /* Dialogue box handle.*/
- int i; /* Line counter. */
- char timestring[8]; /* For times of phenom.*/
- char *linestart[INFOBOX_LINES];/* Array of pointers */
- /* to start of each */
- /* line of info text. */
-
- /* Create dbox. */
- d = dbox_new(SEL_INFO_NAME);
- if (d == NULL) return;
-
- /* Build strings containing times of phenomena, and */
- /* display them in the dbox. */
- build_timestring(timestring,
- selection.rising, selection.rise_hour, selection.rise_min);
- dbox_setfield(d, selinfo_rise, timestring);
- build_timestring(timestring,
- selection.setting, selection.set_hour, selection.set_min);
- dbox_setfield(d, selinfo_set, timestring);
- build_timestring(timestring,
- selection.culminating, selection.cul_hour, selection.cul_min);
- dbox_setfield(d, selinfo_culmin, timestring);
-
- /* Set up pointer to text buffer, and obtain info. */
- infoptr = infobuf;
- module_fns[sel_owner].selectfn(sel_info_request);
-
- /* Cut up returned text string into separate lines, */
- /* obtaining pointers to start of each line. */
- cutup(linestart);
-
- /* Fill in the text lines in the dbox. */
- for (i=0; i < INFOBOX_LINES; i++)
- dbox_setfield(d, selinfo_textline+i, linestart[i]);
-
- /* Display dbox until user cancels or okays it. */
- dbox_show(d);
- dbox_fillin(d);
-
- /* Delete dbox. */
- dbox_dispose(&d);
-
- return;
- }
-
- /*------------------------------------------------------*/
- /* Function to build a string containing the time of a */
- /* phenomenon. */
- /*String pointed to by stringptr is assumed long enough.*/
- /*------------------------------------------------------*/
- static void build_timestring(char *stringptr, BOOL valid, int hour, int min)
- {
- /* If hour and min are not valid, return a suitable */
- /* string. */
- if (!valid)
- {
- sprintf(stringptr, "--:--");
- return;
- }
-
- /* Build time string in style of a 24-hour clock. */
- sprintf(stringptr, "%02.2i:%02.2i", hour, min);
-
- return;
- }
-
-
- /*------------------------------------------------------*/
- /* Handle hits on 'View sel.' Sub-Menu */
- /*------------------------------------------------------*/
-
- static void view_sub_menuproc(char *hit)
- {
- REAL view_alt; /* Altitude of object at time of */
- /* phenomenon. */
- REAL view_azim; /* Azimuth of object at time of */
- /* phenomenon. */
- int best_dir; /* Which of the standard directions */
- /* is best for viewing this azimuth. */
- int selnum; /* Window ID number of object. */
-
- switch (hit[1])
- {
- case view_item_now:
- /* If the object is not in fact visible as billed,*/
- /* quit at once. This should not happen. */
- if (horiz_data.selnum == NOWHERE &&
- vert_data.selnum == NOWHERE) return;
- /* Find the altitude and azimuth of the object now*/
- if (horiz_data.selnum != NOWHERE)
- {
- selnum = horiz_data.selnum;
- view_alt = horiz_list[selnum].alt;
- view_azim = horiz_list[selnum].azim;
- }
- else
- {
- selnum = vert_data.selnum;
- view_alt = vert_list[selnum].alt;
- view_azim = vert_list[selnum].azim;
- }
- /* Set the direction of view to the best one for */
- /* viewing the object (if it is currently */
- /* some other direction). */
- best_dir = nearest_dir(view_azim);
- if (ob_data.dir != best_dir)
- {
- ob_data.dir = best_dir;
- ob_data.ang = direction[ob_data.dir];
- /*Recalc screen coords to reflect new direction.*/
- recalc_horiz_xy();
- recalc_vert_xy();
- /* Invalidate windows. */
- invalidate_all();
- }
- /* Arrange windows appropriately to display object*/
- arrange_windows(view_alt, view_azim);
-
- return;
-
- case view_item_rising:
- /* Change observer data so that the rising of the */
- /* selected object can be viewed. */
- ob_data.hour = selection.rise_hour;
- ob_data.min = selection.rise_min;
- view_alt = (REAL)0.0;
- view_azim = selection.rise_azim;
- ob_data.dir = nearest_dir(view_azim);
- break;
-
- case view_item_setting:
- /* Change observer data so that the setting of */
- /* the selected object can be viewed. */
- ob_data.hour = selection.set_hour;
- ob_data.min = selection.set_min;
- view_alt = (REAL)0.0;
- view_azim = selection.set_azim;
- ob_data.dir = nearest_dir(view_azim);
- break;
-
- case view_item_culminating:
- /* Change observer data so that the culminating */
- /* of the selected object can be viewed. */
- ob_data.hour = selection.cul_hour;
- ob_data.min = selection.cul_min;
- view_alt = selection.cul_alt;
- view_azim = selection.cul_azim;
- ob_data.dir = nearest_dir(view_azim);
- break;
-
- default:
- return;
- }
-
- /* Fill in derived fields of ob_data (ang, jul, etc) */
- fillin_obfields(&ob_data);
-
- /* Rebuild the plotting lists for the new time of day.*/
- build_lists();
-
- /* Update Selection data to correspond to new lists. */
- module_fns[sel_owner].selectfn(timeonly_recalculate);
-
- /* Record new id numbers of selected object. */
- horiz_data.selnum = selection.horiz_id;
- vert_data.selnum = selection.vert_id;
-
- /* Ensure size of Selection frame is valid. */
- if (horiz_data.selnum != NOWHERE)
- calculate_frame(&horiz_data);
- if (vert_data.selnum != NOWHERE)
- calculate_frame(&vert_data);
-
- /* Invalidate windows. */
- invalidate_all();
-
- /* Arrange windows appropriately to display object. */
- arrange_windows(view_alt, view_azim);
-
- return;
- }
-
- /*------------------------------------------------------*/
- /* Function to find which of the standard directions of */
- /* view is the nearest to the given azimuth. */
- /*------------------------------------------------------*/
- static int nearest_dir(REAL azim)
- {
- REAL min_error = (REAL)2.0 * PI;
- REAL error;
- int i;
- int nearest = 0;
-
- for (i=0; i<NDIR; i++)
- {
- error = direction[i] - azim;
- error = (REAL)fabs((double)error);
- if (error < min_error)
- {
- min_error = error;
- nearest = i;
- }
- }
- return nearest;
- }
-
- /*------------------------------------------------------*/
- /* Function to arrange the windows to bring the object */
- /* at the given altitude and azimuth onto the screen. */
- /*------------------------------------------------------*/
- static void arrange_windows(REAL alt, REAL az)
- {
- /* If the given altitude is greater than the maximum */
- /* altitude which appears in the Horiz window, use the */
- /* Vert window. */
- if (alt >= alt_max)
- {
- arrange_vert(alt, az);
- return;
- }
-
- /* Otherwise use the Horiz window. */
- arrange_horiz(alt, az);
-
- return;
- }
-
- /* */
- /* Function to arrange Horiz window appropriately to */
- /* display the object at the given alt and az. */
- /* */
- static void arrange_horiz(REAL alt, REAL az)
- {
- /* Assume Horiz window is at full height (or was when */
- /* it was last open). */
- /* Ensure window is open and on top, and scroll it to */
- /* bring the given azimuth to the centre of the visible */
- /* portion. Ignore altitude. */
-
- wimp_wstate winstate;
- int x_coord; /* x coord corresponding to az. */
- int viswidth; /* Width of visible part of win.*/
- int x_scroll; /* Scroll offset required. */
-
- /* Get current state of Horiz window. */
- wimpt_noerr(wimp_get_wind_state(horiz_handle, &winstate));
-
- /* Calculate current width of visible portion. */
- viswidth = winstate.o.box.x1 - winstate.o.box.x0;
-
- /* Calculate x coord corresponding to given azimuth. */
- x_coord = x_h(az);
-
- /* Calculate scroll offset needed to put x_coord into */
- /* centre of visible portion. */
- x_scroll = x_coord - (viswidth/2);
-
- /* Make sure x_scroll is valid. */
- if (x_scroll < horiz_size.x0)
- x_scroll = horiz_size.x0;
- if (x_scroll + viswidth > horiz_size.x1)
- x_scroll = horiz_size.x1 - viswidth;
-
- /* Call Wimp_OpenWindow with new value of x_scroll. */
- /* Also, ensure Horiz window is on top of stack. */
- winstate.o.x = x_scroll;
- winstate.o.behind = -1;
- wimpt_noerr(wimp_open_wind(&winstate.o));
-
- return;
- }
-
- /* */
- /* Function to arrange Vert window appropriately to */
- /* display object at given alt and az. */
- /* */
- static void arrange_vert(REAL alt, REAL az)
- {
- /* Assume Vert window is at full size (or was when it */
- /* was last open). */
- /* Ensure window is open and on top of stack. */
-
- wimp_wstate winstate;
-
- /* Get current state of Vert window. */
- wimpt_noerr(wimp_get_wind_state(vert_handle, &winstate));
-
- /* Call Wimp_OpenWindow, ensuring Vert window is on top */
- /* of stack. */
- winstate.o.behind = -1;
- wimpt_noerr(wimp_open_wind(&winstate.o));
-
- return;
- }
-
- /*------------------------------------------------------*/
- /* Function to invoke Select function appropriate to */
- /* hit on Select sub-menu */
- /*------------------------------------------------------*/
- static void invoke_selectfns(char *hit)
- {
- selectfntype *appropriate_fn;
- int module_no; /* For module no. of owner of this */
- /* menu entry. */
-
- /* For unknown option, do nothing */
- if (hit[1] < 1 ) return;
- if (hit[1] > select_count) return;
-
- /* Find which module owns this menu entry. */
- module_no = sel_index[hit[1]];
-
- /* Give modules access to list of submenu hits. */
- module_submenu_hits = hit+2;
-
- /* Find appropriate Select function. */
- appropriate_fn = module_fns[module_no].selectfn;
-
- /* Set looping flag to FALSE. Might be changed by module*/
- dbox_persisting = FALSE;
-
- /* Enclose module call in loop. End when flag is FALSE. */
- do
- {
-
- /* Invoke appropriate Select function. */
- appropriate_fn(new_selection);
-
- /* Establish new selection, if dialogue with user was */
- /* successful. */
- if (selection.selected_OK)
- establish_new_selection(module_no);
-
- /* End of loop for persisting dbox. */
- }
- while (dbox_persisting);
-
- /* List of submenu hits no longer valid. */
- module_submenu_hits = NULL;
-
- return;
- }
-
- /*------------------------------------------------------*/
- /* Function to establish a new selected object. */
- /*------------------------------------------------------*/
- static void establish_new_selection(int new_owner)
- {
-
- /* Remove frame around old selection (if one is */
- /* currently in window). */
- if (selection_exists)
- {
- if (horiz_data.selnum != NOWHERE)
- invalidate_framearea(horiz_handle, horiz_data);
- if (vert_data.selnum != NOWHERE)
- invalidate_framearea(vert_handle, vert_data);
- }
-
- /* Flag the existence of new selection. */
- selection_exists = TRUE;
-
- /* Record the new owner of the selection. */
- sel_owner = new_owner;
-
- /* Record window number of new selection. Number = */
- /* NOWHERE if selection is not in window. */
- horiz_data.selnum = selection.horiz_id;
- vert_data.selnum = selection.vert_id;
-
- /* Establish new frame (if selected object is in window)*/
- if (horiz_data.selnum != NOWHERE)
- establish_new_frame(horiz_handle, &horiz_data);
- if (vert_data.selnum != NOWHERE)
- establish_new_frame(vert_handle, &vert_data);
-
- return;
- }
-
- /*------------------------------------------------------*/
- /* Function to invalidate the part of the window */
- /* containing the frame around the selected object. */
- /*------------------------------------------------------*/
- static void invalidate_framearea(wimp_w whandle, sv_windata wdat)
- {
- wimp_redrawstr r;
-
- /* Point to selected object: */
- plotobj *selptr = (wdat.listptr + wdat.selnum);
-
- /* Get x and y coords of selected object. */
- int x = selptr->wind_x;
- int y = selptr->wind_y;
-
- /* Shift frame's bounding box to coords of object. */
- /* Put result into redrawstr. */
- coords_offsetbox(&wdat.sel_bounds, x, y, &r.box);
-
- /* Fill in window handle. */
- r.w = whandle;
-
- /* Invalidate the part of the window containing the */
- /* frame. */
- wimpt_noerr(wimp_force_redraw(&r));
-
- return;
- }
-
-
- /*------------------------------------------------------*/
- /* Function to establish frame around new selection. */
- /*------------------------------------------------------*/
- static void establish_new_frame(wimp_w whandle, sv_windata *wd)
- {
-
- /* Calculate coords of frame and bounding box for */
- /* frame, and write them into window's data block. */
- calculate_frame(wd);
-
- /* Invalidate the part of the window which is to */
- /* contain the new frame. */
- invalidate_framearea(whandle, *wd);
-
- return;
- }
-
- /*------------------------------------------------------*/
- /* Function to calculate coords of frame around */
- /* selection, and coords of bounding box of frame, */
- /* and write them into the window's data block. */
- /*------------------------------------------------------*/
- static void calculate_frame(sv_windata *wd)
- {
-
- wimp_box size;
-
- /* Read size of new selected object. */
- size = (wd->listptr + wd->selnum)->size;
-
- /* Construct a frame larger than size and centered */
- /* on 0,0. */
- wd->sel_frame.w = 2*(size.x1 - size.x0);
- wd->sel_frame.h = 2*(size.y1 - size.y0);
- wd->sel_frame.x = -(wd->sel_frame.w)/2;
- wd->sel_frame.y = -(wd->sel_frame.h)/2;
-
- /* Set up bounding box which encloses frame. */
- wd->sel_bounds.x0 = wd->sel_frame.x - 4;
- wd->sel_bounds.y0 = wd->sel_frame.y - 4;
- wd->sel_bounds.x1 = wd->sel_frame.x +\
- wd->sel_frame.w + 6;
- wd->sel_bounds.y1 = wd->sel_frame.y +\
- wd->sel_frame.h + 6;
-
- return;
- }
-
- /*********** 'Display' Options for Modules **************/
- /*------------------------------------------------------*/
- /* Function to invoke display function appropriate */
- /* to hit on Display sub-menu. */
- /*------------------------------------------------------*/
- static void invoke_displayfns(char *hit)
- {
- BOOL w_invalid;/* TRUE if windows become invalid. */
- int module_no; /* For module no. of owner of this */
- /* menu entry. */
- displayfntype *appropriate_fn;
-
- /* For unknown option, do nothing */
- if (hit[1] < 1 ) return;
- if (hit[1] > display_count) return;
-
- /* Give modules access to list of submenu hits. */
- module_submenu_hits = hit+2;
-
- /* Find owner of this menu entry. */
- module_no = disp_index[hit[1]];
-
- /* Find appropriate Display function. */
- appropriate_fn = module_fns[module_no].dispfn;
-
- /* Set looping flag to FALSE. Might be changed by module*/
- dbox_persisting = FALSE;
-
- /* Enclose module call in loop. End when flag is FALSE. */
- do
- {
-
- /* Set rebuilding flag to FALSE. Module can change it.*/
- rebuild_request = FALSE;
- /* Invoke appropriate display function. */
- w_invalid = appropriate_fn(&enabled[module_no]);
-
- /* Set tick on menu entry accordingly. */
- menu_setflags(display_sub_menu, hit[1], enabled[module_no], 0);
-
- /* Make sure a Selection cannot be made on a disabled */
- /* module. If module has a Select entry, set the fade */
- /* status of that entry according to the value of the */
- /* tick flag just returned. */
- if (module_index[module_no] > 0)
- menu_setflags(sel_sub_menu, module_index[module_no],\
- 0, !enabled[module_no]);
-
- /* If module is now disabled, and it was the owner of */
- /* the selection, cancel the selection. */
- if (module_no==sel_owner && !enabled[module_no])
- cancel_selection();
-
- /* Declare windows invalid, if necessary. */
- if (w_invalid || rebuild_request) invalidate_all();
-
- /* Rebuild plotting lists, if necessary. */
- if (rebuild_request) display_rebuild();
-
-
- /* End of loop for persisting dbox. */
- }
- while (dbox_persisting);
-
- /* List of submenu hits no longer valid. */
- module_submenu_hits = NULL;
-
- return;
- }
-
- /*------------------------------------------------------*/
- /* Function to rebuild plotting lists, at the request */
- /* of a Display function. */
- /*------------------------------------------------------*/
- static void display_rebuild(void)
- {
-
- build_lists();
-
- /* Nothing more to do if there is no selected object. */
- if (!selection_exists) return;
-
- /* Call selection function for owner of object. Reason */
- /* 'timeonly_recalculate' will do. */
- module_fns[sel_owner].selectfn(timeonly_recalculate);
-
- /* Record new id numbers of selected object. */
- horiz_data.selnum = selection.horiz_id;
- vert_data.selnum = selection.vert_id;
-
- /* If object is on view, make sure coords of frame and */
- /* bounding box are valid. */
- if (horiz_data.selnum != NOWHERE)
- calculate_frame(&horiz_data);
- if (vert_data.selnum != NOWHERE)
- calculate_frame(&vert_data);
-
- return;
- }
-
-
- /********************************************************/
- /* Info Box Handler */
- /********************************************************/
-
- static void sv_info_about_program(void)
- {
- dbox d; /* Dialogue box handle */
- char versionstring[256];
-
- if (d = dbox_new("progInfo"), d != NULL)
- {
- sprintf(versionstring, "%s (%s) ",VERSION,__DATE__);
- dbox_setfield(d, sv_info_field, versionstring);
-
- dbox_show(d); /* display it */
- dbox_fillin(d); /* maintain it */
- dbox_dispose(&d); /* remove it */
- }
- }
-
-
- /********************************************************/
- /* Functions for Observer Details */
- /********************************************************/
-
- /*------------------------------------------------------*/
- /* Function to obtain new Observer Details */
- /* and update windows accordingly. */
- /*------------------------------------------------------*/
- static void observer(void)
- {
- int response; /* Which action button has just */
- /* been been pressed. */
- int target; /* Value that the Day field */
- /* "wants" to have. */
- BOOL keep_open; /* TRUE if the dbox is to remain */
- /* open after the present button */
- /* has been processed. */
- int year; /* For changing century. */
- char buf[10]; /* For changing N/S and E/W. */
-
- /* Load dbox with the settings currently in force. */
- data_to_box(ob_data);
-
- /* Put Observer Box on screen. */
- dbox_show(d_ob);
-
- /* Set value of target. */
- target = dbox_getnumeric(d_ob, dayf);
-
-
- /* Loop until Select on 'OK', or 'close' request. */
-
- do
- {
- /* Get number of action button pressed by the user. */
- response = dbox_fillin(d_ob);
-
- /* Take appropriate action. */
- switch (response) {
-
- case ob_close_rq:
- /* Do nothing. Data on display may be invalid, */
- /* but box is being closed anyway. */
- keep_open = FALSE;
- break;
-
- case ob_cancel_butt:
- /* Put the current data back on display. */
- data_to_box(ob_data);
- /* Reset the value of target. */
- target = dbox_getnumeric(d_ob, dayf);
- /* Keep dbox open if user has so requested. */
- keep_open = dbox_persist();
- break;
-
- case ob_ok_butt:
- /* Call handler function for clicks on OK button. */
- ob_ok_click();
- /* Reset the value of target. */
- target = dbox_getnumeric(d_ob, dayf);
- /* Keep dbox open if user has so requested. */
- keep_open = dbox_persist();
- break;
-
- case set_butt:
- /* Set Default to the data now on display in */
- /* the dbox. (This is not necessarily the same */
- /* as the settings currently in force.) */
- /* If error, report it & continue. */
- if (!save_ob_data())
- {
- werr(NON_FATAL, "Can't set defaults");
- keep_open = TRUE;
- }
- else
- /* Reset the value of target, and */
- /* Keep dbox open if user has so requested. */
- {
- target = dbox_getnumeric(d_ob, dayf);
- keep_open = dbox_persist();
- }
- break;
-
- case show_butt:
- /* Load the default settings into the dbox, for */
- /* user to inspect, alter, or whatever. */
- /* If error, report it & continue. */
- if (!load_ob_data())
- werr(NON_FATAL, "Can't load defaults");
- else
- /* Reset the value of target. */
- target = dbox_getnumeric(d_ob, dayf);
- /* Keep dbox open. */
- keep_open = TRUE;
- break;
-
- case sys_date_butt:
- /* Write the date from the system clock into */
- /* the dbox. */
- load_sys_date();
- /* Reset the value of target. */
- target = dbox_getnumeric(d_ob, dayf);
- /* Keep dbox open. */
- keep_open = TRUE;
- break;
-
- case cent_butt:
- /* Toggle between 20th and 21st centuries. */
- year = dbox_getnumeric(d_ob, yrf);
- year = (year >= 2000 ? year-100 : year+100);
- dbox_setnumeric(d_ob, yrf, year);
- /* Keep dbox open. */
- keep_open = TRUE;
- break;
-
- case ns_butt: case n_or_s:
- /* Toggle between N and S latitude. */
- dbox_getfield(d_ob, nsf, buf, 10);
- buf[0] = (buf[0]=='N'? 'S' : 'N');
- dbox_setfield(d_ob, nsf, buf);
- /* Keep dbox open. */
- keep_open = TRUE;
- break;
-
- case ew_butt: case e_or_w:
- /* Toggle between E and W longitude. */
- dbox_getfield(d_ob, ewf, buf, 10);
- buf[0] = (buf[0]=='W'? 'E' : 'W');
- dbox_setfield(d_ob, ewf, buf);
- /* Keep dbox open. */
- keep_open = TRUE;
- break;
-
- default:
- /* Must be one of the date / time changing butts. */
- /* Call function to handle clicks on arrows. */
- ob_arrows(response, &target);
- /* Keep dbox open. */
- keep_open = TRUE;
- break;
- }
-
- } while (keep_open);
-
- /* Remove dbox from screen */
- dbox_hide(d_ob);
-
- return;
- }
-
-
- /*------------------------------------------------------*/
- /* Handle clicks on data-changing buttons */
- /* in Observer Box */
- /*------------------------------------------------------*/
- static void ob_arrows(int response, int *targptr)
- {
- char numstring[10];/* For number / string conversions */
-
- int lati;
- int latd;
- int lat10;
- int longi;
- int longd;
- int long10;
- int day;
- int month;
- int year;
- int lastday; /* Last day of the month. */
- int hour;
- int min;
- float offset;
-
- switch (response) {
-
- /* Latitude (integer part) */
- case lai_tu: case lai_td: case lai_uu: case lai_ud:
- lati = dbox_getnumeric(d_ob, laif);
- latd = dbox_getnumeric(d_ob, ladf);
- lati += addon[lai_ud-response];
- lat10 = 10*lati + latd;
- if (lat10 < 900 && lat10 >= 0)
- {
- /* Set integer field of latitude display. */
- sprintf(numstring, "%02.2i", lat10/10);
- dbox_setfield(d_ob, laif, numstring);
- }
- break;
-
- /* Latitude (decimal part) */
- case lad_uu: case lad_ud:
- lati = dbox_getnumeric(d_ob, laif);
- latd = dbox_getnumeric(d_ob, ladf);
- latd += addon[lad_ud-response];
- lat10 = 10*lati + latd;
- if (lat10 < 900 && lat10 >= 0)
- {
- /* Set both fields of latitude display. */
- sprintf(numstring, "%02.2i", lat10/10);
- dbox_setfield(d_ob, laif, numstring);
- dbox_setnumeric(d_ob, ladf, lat10%10);
- }
- break;
-
- /* Longitude (integer part) */
- case loi_hu: case loi_hd: case loi_tu:
- case loi_td: case loi_uu: case loi_ud:
- longi = dbox_getnumeric(d_ob, loif);
- longd = dbox_getnumeric(d_ob, lodf);
- longi += addon[loi_ud-response];
- long10 = 10*longi + longd;
- if (long10 <= 1800 && long10 >= 0)
- {
- /* Set integer field of longitude display. */
- sprintf(numstring, "%03.3i", long10/10);
- dbox_setfield(d_ob, loif, numstring);
- }
- break;
-
- /* Longitude (decimal part) */
- case lod_uu: case lod_ud:
- longi = dbox_getnumeric(d_ob, loif);
- longd = dbox_getnumeric(d_ob, lodf);
- longd += addon[lod_ud-response];
- long10 = 10*longi + longd;
- if (long10 <= 1800 && long10 >= 0)
- {
- /* Set both fields of longitude display. */
- sprintf(numstring, "%03.3i", long10/10);
- dbox_setfield(d_ob, loif, numstring);
- dbox_setnumeric(d_ob, lodf, long10%10);
- }
- break;
-
- /* Years */
- case yr_tu: case yr_td: case yr_uu: case yr_ud:
- year = dbox_getnumeric(d_ob, yrf);
- year += addon[yr_ud-response];
- if (year <= 2099 && year >= 1900)
- {
- /* Set year field. Make day field as close as */
- /* possible to its target, while keeping it valid.*/
- dbox_setnumeric(d_ob, yrf, year);
- month = dbox_getnumeric(d_ob, monf);
- lastday = daysin[leap(year)][month];
- day = (*targptr > lastday ? lastday : *targptr);
- sprintf(numstring, "%02.2i", day);
- dbox_setfield(d_ob, dayf, numstring);
- }
- break;
-
- /* Months */
- case mon_tu: case mon_td: case mon_uu: case mon_ud:
- year = dbox_getnumeric(d_ob, yrf );
- month = dbox_getnumeric(d_ob, monf);
- month += addon[mon_ud-response];
- if (month <= 12 && month > 0)
- {
- /* Set month field. Make day field as close as */
- /* possible to its target, while keeping it valid.*/
- sprintf(numstring, "%02.2i", month);
- dbox_setfield(d_ob, monf, numstring);
- year = dbox_getnumeric(d_ob, yrf );
- lastday = daysin[leap(year)][month];
- day = (*targptr > lastday ? lastday : *targptr);
- sprintf(numstring, "%02.2i", day);
- dbox_setfield(d_ob, dayf, numstring);
- }
- break;
-
- /* Days */
- case day_tu: case day_td: case day_uu: case day_ud:
- year = dbox_getnumeric(d_ob, yrf );
- month= dbox_getnumeric(d_ob, monf);
- day = dbox_getnumeric(d_ob, dayf);
- day += addon[day_ud-response];
- lastday = daysin[leap(year)][month];
- if (day <= lastday && day > 0)
- {
- /* Set day field and change value of target. */
- sprintf(numstring, "%02.2i", day);
- dbox_setfield(d_ob, dayf, numstring);
- *targptr = day;
- }
- break;
-
- /* Hours */
- case hr_tu: case hr_td: case hr_uu: case hr_ud:
- hour = dbox_getnumeric(d_ob, hrf);
- hour += addon[hr_ud-response];
- if (hour <= 23 && hour >= 0)
- {
- sprintf(numstring, "%02.2i", hour);
- dbox_setfield(d_ob, hrf, numstring);
- }
- break;
-
- /* Minutes */
- case min_tu: case min_td: case min_uu: case min_ud:
- min = dbox_getnumeric(d_ob, minf);
- min += addon[min_ud-response];
- if (min <= 59 && min >= 0)
- {
- sprintf(numstring, "%02.2i", min);
- dbox_setfield(d_ob, minf, numstring);
- }
- break;
-
- /* Time offset */
- case off_uu: case off_ud: case off_xu: case off_xd:
- dbox_getfield(d_ob, offf, numstring, 10);
- sscanf(numstring, "%f", &offset);
- offset += offset_incr[off_xd - response];
- if (offset >= -15.0f && offset <= 15.0f)
- {
- sprintf(numstring, "%+05.1f", (double)offset);
- dbox_setfield(d_ob, offf, numstring);
- }
- break;
-
- default:
- break;
-
- }
- return;
- }
-
-
- /*------------------------------------------------------*/
- /* Handle clicks on OK in Observer Box */
- /*------------------------------------------------------*/
- static void ob_ok_click(void)
- {
- observerstr new_data; /* New data read from dbox. */
-
- BOOL dir_changed = FALSE;/* Becomes TRUE if user */
- /* changes direction of view.*/
- BOOL dat_changed = FALSE;/* Becomes TRUE if user */
- /* changes date field. */
- BOOL tim_changed = FALSE;/* Becomes TRUE if user */
- /* changes time field. */
- BOOL off_changed = FALSE;/* Becomes TRUE if user */
- /* changes time offset. */
- BOOL loc_changed = FALSE;/* Becomes TRUE if user */
- /* changes location. */
- BOOL dir_only = FALSE;/* Becomes TRUE if user */
- /* changes just the direction*/
- BOOL tim_dir_only= TRUE; /* Becomes FALSE if user */
- /* changes dat, loc or offset*/
- BOOL any_changed = FALSE;/* Becomes TRUE if user */
- /* changes any of the data. */
-
- /* Read new data from dbox */
- data_from_box(&new_data);
-
- /* Give special treatment if this is the first time. */
- if (!observer_verified)
- {
- /* Update observer data to match data read from box.*/
- ob_data = new_data;
-
- /* Flag observer data as verified. */
- observer_verified = TRUE;
-
- /* Build plotting lists. */
- build_lists();
-
- return;
- }
-
- /* Normal Processing. */
-
- /* Examine new data to find out what's changed. */
- /* Note 'date' and 'time' here refer to the values app- */
- /* earing in the dbox. Need to look at 'offset' field */
- /* as well in order to detect changes. */
- off_changed = (fabs((double)new_data.offset - (double)ob_data.offset)
- >= 0.1);
- dir_changed = (new_data.dir != ob_data.dir);
- dat_changed = (new_data.day != ob_data.day ||
- new_data.month != ob_data.month ||
- new_data.year != ob_data.year);
- tim_changed = (new_data.hour != ob_data.hour ||
- new_data.min != ob_data.min);
- loc_changed = (new_data.lat10 != ob_data.lat10 ||
- new_data.isn != ob_data.isn ||
- new_data.long10 != ob_data.long10 ||
- new_data.isw != ob_data.isw);
- dir_only = dir_changed && !dat_changed && \
- !tim_changed && !off_changed && !loc_changed;
- tim_dir_only= !dat_changed && !off_changed && !loc_changed;
- any_changed = dir_changed || dat_changed || \
- tim_changed || loc_changed || off_changed;
-
-
- /* Do nothing if no changes have been made. */
- if (!any_changed)
- return;
-
- /* Change Observer Details to match new data. */
- ob_data = new_data;
-
- /* Invalidate the windows. */
- invalidate_all();
-
- /* If the direction alone has changed, just re-calculate*/
- /* the screen coords and then return. */
- if (dir_only)
- {
- recalc_horiz_xy();
- recalc_vert_xy();
- return;
- }
- /*
- * The date or time have changed, so rebuild the
- * plotting lists, and re-calculate when the
- * selected object (if any) is visible.
- */
- build_lists();
-
- if (selection_exists)
- {
- /* Set special reason code if nothing but the time */
- /* (and possibly the direction as well - this is of */
- /* no importance) has changed. */
- int reason = (tim_dir_only? \
- timeonly_recalculate : recalculate_data);
-
- /* Call Selection function for owner of object. */
- module_fns[sel_owner].selectfn(reason);
- /* Record new id numbers of selected object. */
- horiz_data.selnum = selection.horiz_id;
- vert_data.selnum = selection.vert_id;
- /* If object is on view, ensure coords of frame and */
- /* bounding box of frame are valid. */
- if (horiz_data.selnum != NOWHERE)
- calculate_frame(&horiz_data);
- if (vert_data.selnum != NOWHERE)
- calculate_frame(&vert_data);
- }
-
- return;
- }
-
- /*------------------------------------------------------*/
- /* Fn to build plotting lists. */
- /*------------------------------------------------------*/
- static void build_lists(void)
- {
- int i;
- buildfntype *bfn;
-
- /* Turn hour glass on. */
- visdelay_begin();
-
- /* Reset number of objects to zero. */
- horiz_data.number = 0;
- vert_data.number = 0;
-
- for (i=0; i < module_count; i++)
- {
- bfn = module_fns[i].buildfn;
- if (bfn != NULL) bfn();
- }
-
- /* Turn hour glass off. */
- visdelay_end();
-
- return;
- }
-
- /*------------------------------------------------------*/
- /* Fn to declare all parts of both windows invalid */
- /*------------------------------------------------------*/
- static void invalidate_all(void)
- {
- wimp_redrawstr r;
-
- r.w = horiz_handle;
- r.box = horiz_size;
- wimpt_noerr(wimp_force_redraw(&r));
- r.w = vert_handle;
- r.box = vert_size;
- wimpt_noerr(wimp_force_redraw(&r));
-
- return;
- }
-
- /*------------------------------------------------------*/
- /* Fn to write data into Observer Details box */
- /*------------------------------------------------------*/
- static void data_to_box(observerstr data)
- {
- int i;
- char numstring[10];
-
- /* Set Latitude field (integer part, then decimal). */
- sprintf(numstring, "%02.2i", data.lat10/10);
- dbox_setfield(d_ob, laif, numstring);
- dbox_setnumeric(d_ob, ladf, data.lat10%10);
-
- /* Set N or S for Latitude. */
- dbox_setfield(d_ob, nsf, (data.isn? "N" : "S"));
-
- /* Set Longitude field (integer part, then decimal). */
- sprintf(numstring, "%03.3i", data.long10/10);
- dbox_setfield(d_ob, loif, numstring);
- dbox_setnumeric(d_ob, lodf, data.long10%10);
-
- /* Set E or W for Longitude. */
- dbox_setfield(d_ob, ewf, (data.isw? "W" : "E"));
-
- /* Set Day field. */
- sprintf(numstring, "%02.2i", data.day);
- dbox_setfield(d_ob, dayf, numstring);
-
- /* Set Month field. */
- sprintf(numstring, "%02.2i", data.month);
- dbox_setfield(d_ob, monf, numstring);
-
- /* Set Year field. */
- dbox_setnumeric(d_ob, yrf, data.year);
-
- /* Set Hour field. */
- sprintf(numstring, "%02.2i", data.hour);
- dbox_setfield(d_ob, hrf, numstring);
-
- /* Set Minute field. */
- sprintf(numstring, "%02.2i", data.min);
- dbox_setfield(d_ob, minf, numstring);
-
- /* Set Offset field. */
- sprintf(numstring, "%+05.1f", (double)data.offset);
- dbox_setfield(d_ob, offf, numstring);
-
- /* Set 'direction' radio buttons. */
- for (i=0; i<NDIR; i++)
- dbox_setnumeric(d_ob, DIR_BASE+i, (i==data.dir? 1 : 0));
-
- return;
- }
-
-
- /*------------------------------------------------------*/
- /* Fn to read data from Observer Details box */
- /*------------------------------------------------------*/
- static void data_from_box(observerstr *ptr)
- {
- int i;
- int d;
- char buf[10];
-
- /* Read latitude*10. Combine integer and decimal parts.*/
- i = dbox_getnumeric(d_ob, laif);
- d = dbox_getnumeric(d_ob, ladf);
- ptr->lat10 = 10*i + d;
-
- /* Read N or S for latitude. */
- dbox_getfield(d_ob, nsf, buf, 10);
- ptr->isn = (buf[0]=='N');
-
- /* Construct latitude in radians. */
- ptr->latit = CONV*(REAL)ptr->lat10/(REAL)10;
- if (!ptr->isn)
- ptr->latit = -ptr->latit;
-
- /* Read longitude*10. Combine integer and decimal parts.*/
- i = dbox_getnumeric(d_ob, loif);
- d = dbox_getnumeric(d_ob, lodf);
- ptr->long10 = 10*i + d;
-
- /* Read E or W for longitude. */
- dbox_getfield(d_ob, ewf, buf, 10);
- ptr->isw = (buf[0]=='W');
-
- /* Construct longitude in radians. */
- ptr->longit = CONV*(REAL)ptr->long10/(REAL)10;
- if (!ptr->isw)
- ptr->longit = -ptr->longit;
-
- /* Read day. */
- ptr->day = dbox_getnumeric(d_ob, dayf);
-
- /* Read month. */
- ptr->month = dbox_getnumeric(d_ob, monf);
-
- /* Read year. */
- ptr->year = dbox_getnumeric(d_ob, yrf);
-
- /* Read hour. */
- ptr->hour = dbox_getnumeric(d_ob, hrf);
-
- /* Read minute. */
- ptr->min = dbox_getnumeric(d_ob, minf);
-
- /* Read time offset. */
- dbox_getfield(d_ob, offf, buf, 10);
- sscanf(buf, "%f", &ptr->offset);
-
- /* Read direction. */
- /* Search the 'direction' radio buttons for the one */
- /* that is ON. */
- for (i=NDIR-1;\
- i>0 && dbox_getnumeric(d_ob, DIR_BASE+i)==0;\
- i--)
- ;
- /* Set dir field. */
- ptr->dir = i;
-
- /* Fill in derived fields of observer data. */
- fillin_obfields(ptr);
-
- return;
- }
-
- /*------------------------------------------------------*/
- /* Function to fill in the derived fields of the */
- /* observerstr pointed to by ptr. */
- /*------------------------------------------------------*/
- static void fillin_obfields(observerstr *ptr)
- {
-
- /* Set ang field to angle corresponding to dir field. */
- ptr->ang = direction[ptr->dir];
-
- /* Calculate days since 12:00 on 00/01/1900 */
- ptr->jul = datime_julian(ptr, ptr->hour, ptr->min);
-
- /* Set local siderial time. */
- ptr->sid = datime_siderial(ptr, ptr->jul, ptr->hour, ptr->min);
-
- return;
- }
-
- /*------------------------------------------------------*/
- /* Function to save Observer Data to disc */
- /*------------------------------------------------------*/
- static BOOL save_ob_data(void)
- {
- observerstr new_data[1]; /* For data read from dbox. */
- FILE *defaults; /* File handle. */
- size_t numwritten;
-
- /* Open disc file for writing. Quit if error. */
- defaults = fopen(data_file, "wb");
- if (defaults == NULL) return FALSE;
-
- /* Read new data from dbox. */
- data_from_box(new_data);
-
- /* Write Observer Details. */
- numwritten = fwrite((void *)new_data, sizeof(observerstr), 1, defaults);
-
- /* Close file. Fatal error if it won't close. */
- if (fclose(defaults) != 0)
- werr(FATAL, "SkyView Error: Can't close Default file");
-
- /* Return success or failure. */
- return (numwritten == 1);
- }
-
- /*------------------------------------------------------*/
- /* Function to load Observer Data from disc */
- /*------------------------------------------------------*/
- static BOOL load_ob_data(void)
- {
- observerstr new_data[1]; /* For data read from disc. */
- FILE *defaults; /* File handle. */
- size_t numread;
-
- /* Open disc file for reading. Quit if error. */
- defaults = fopen(data_file, "rb");
- if (defaults == NULL) return FALSE;
-
- /* Attempt to read Observer Details. */
- numread = fread((void *)new_data, sizeof(observerstr), 1, defaults);
-
- /* Close disc file. Fatal error if it won't close. */
- if (fclose(defaults) != 0)
- werr(FATAL, "SkyView Error: Can't close Default file");
-
- /* If read failed, do not load dbox. */
- if (numread != 1) return FALSE;
-
- /* All OK. Load data into dbox & return TRUE. */
- data_to_box(new_data[0]);
- return TRUE;
- }
-
-
- /*------------------------------------------------------*/
- /* Function to load System Date into dbox. */
- /*------------------------------------------------------*/
- static void load_sys_date(void)
- {
- time_t encoded_time;
- struct tm *sys_time;
- char numstring[10]; /* For No.-to-string conversions */
-
- /* Read system time. */
- encoded_time = time(NULL);
- if (encoded_time == (time_t)-1)
- return;
- sys_time = localtime(&encoded_time);
-
- /* Set Day field. */
- sprintf(numstring, "%02.2i", sys_time->tm_mday);
- dbox_setfield(d_ob, dayf, numstring);
-
- /* Set Month field. */
- sprintf(numstring, "%02.2i", 1 + sys_time->tm_mon);
- dbox_setfield(d_ob, monf, numstring);
-
- /* Set Year field. */
- dbox_setnumeric(d_ob, yrf, 1900 + sys_time->tm_year);
-
- return;
- }
-
-
- /*------------------------------------------------------*/
- /* Raw Event Handler for Observer Box */
- /*------------------------------------------------------*/
- static BOOL ob_raw_handler(dbox d, void *event, void *handle)
-
- /* Prevent a click with Adjust from clearing ALL the */
- /* 'direction' radio buttons at the same time. */
-
- {
- wimp_eventstr *e=(wimp_eventstr *)event;
- wimp_i icon;
-
- if (e->e == wimp_EBUT &&\
- e->data.but.m.bbits == wimp_BRIGHT)
- {
- icon = e->data.but.m.i;
- if (icon>=1 &&\
- icon<=8 &&\
- dbox_getnumeric(d,icon)==0)
- {
- dbox_setnumeric(d,icon,TRUE);
- return TRUE;
- }
- }
- return FALSE;
- }
-
-
- /********************************************************/
- /* Handling of Select on Icon Bar Icon */
- /********************************************************/
-
- static void sv_iconclick(wimp_i icon)
- {
- return;
- }
-
-
- /********************************************************/
- /* Function to add new object to plotting list. */
- /********************************************************/
-
- void addobj(plotobj new_object, int *horiz_id, int *vert_id)
- {
-
-
- /* Add new object to Horiz window if it is above the */
- /* horizon but below alt_max, and if there is room in */
- /* the plotting list. */
-
- if (horiz_data.number < MAXOBJS && \
- new_object.alt > (REAL)0.0 && \
- new_object.alt <= alt_max)
- {
- /* Fill in the remaining info */
- /*(ie screen coords, bounding box, pointer to next).*/
- new_object.wind_x = x_h(new_object.azim);
- new_object.wind_y = y_h(new_object.alt);
- coords_offsetbox(&new_object.size, \
- new_object.wind_x, \
- new_object.wind_y, \
- &new_object.bounds);
- new_object.next = 0;
-
- /* Add new object to list, and return an id number */
- /* to the calling module. */
- horiz_list[horiz_data.number] = new_object;
- *horiz_id = horiz_data.number++;
- }
- else
- /* Inform calling module that obj is not in window. */
- *horiz_id = NOWHERE;
-
-
- /* Add new object to Vert window if it is above */
- /* alt_min, and if there is room in the plotting list. */
-
- if (vert_data.number < MAXOBJS && \
- new_object.alt >= alt_min)
- {
- /* Fill in the remaining info */
- /*(ie screen coords, bounding box, pointer to next).*/
- xy_v( new_object.alt, new_object.azim, \
- &new_object.wind_x, &new_object.wind_y);
- coords_offsetbox(&new_object.size, \
- new_object.wind_x, \
- new_object.wind_y, \
- &new_object.bounds);
- new_object.next = 0;
-
- /* Add new object to list, and return an id number */
- /* to the calling module. */
- vert_list[vert_data.number] = new_object;
- *vert_id = vert_data.number++;
- }
- else
- /* Inform calling module that obj is not in window. */
- *vert_id = NOWHERE;
-
-
- return;
- }
-
-
- /********************************************************/
- /* Functions to re-calculate screen x and y values */
- /* following change of direction of view */
- /********************************************************/
- /*------------------------------------------------------*/
- /* Horiz Window xy */
- /*------------------------------------------------------*/
- static void recalc_horiz_xy(void)
- {
- plotobj *p;
- /* Point to end of Horiz list: */
- plotobj *pend = horiz_list + horiz_data.number;
-
- for(p = horiz_list; p < pend; p++)
- {
- /* Fill in x, y, bounding box and pointer to next. */
- p->wind_x = x_h(p->azim);
- p->wind_y = y_h(p->alt);
- coords_offsetbox(&p->size, p->wind_x, p->wind_y, &p->bounds);
- p->next = 0;
- }
-
- return;
- }
-
- /*------------------------------------------------------*/
- /* Vert Window xy */
- /*------------------------------------------------------*/
- static void recalc_vert_xy(void)
- {
- plotobj *p;
- /* Point to end of Vert list: */
- plotobj *pend = vert_list + vert_data.number;
-
- for (p = vert_list; p < pend; p++)
- {
- /* Fill in x, y, bounding box and pointer to next. */
- xy_v(p->alt, p->azim, &p->wind_x, &p->wind_y);
- coords_offsetbox(&p->size, p->wind_x, p->wind_y, &p->bounds);
- p->next = 0;
- }
-
- return;
- }
-
- /********************************************************/
- /* Function to register a module. */
- /********************************************************/
- BOOL register_module(initfntype *initfn)
- {
- BOOL text_null; /* TRUE for null menu entries. */
- modulestr new_module; /* For info on new module. */
-
- /*------------------------------------------------------*/
- /* Check there is space to register module. */
- /*------------------------------------------------------*/
- if (module_count >= MAXMODULES) return FALSE;
-
- /*------------------------------------------------------*/
- /* Obtain Module Info */
- /*------------------------------------------------------*/
- /* Call initialisation function and obtain info on */
- /* new module. Abandon if initialisation fails. */
- if (!initfn(module_count, &new_module)) return FALSE;
-
- /*------------------------------------------------------*/
- /* Record whether module is initially enabled or */
- /* initially disabled. */
- /*------------------------------------------------------*/
- enabled[module_count]=new_module.initial;
-
- /*------------------------------------------------------*/
- /* Record new List-Building function */
- /*------------------------------------------------------*/
- module_fns[module_count].buildfn = new_module.buildfn;
-
- /*------------------------------------------------------*/
- /* Record new Info Function */
- /*------------------------------------------------------*/
- module_fns[module_count].infofn = new_module.infofn;
-
- /*------------------------------------------------------*/
- /* Deal with Select function. */
- /*------------------------------------------------------*/
- /* Check for illegal combinations of NULL items. */
-
- text_null = (*new_module.select_entry == '\0');
- /* Quit if select fn is NULL but text entry isn't. */
- if (new_module.selectfn == NULL && !text_null)
- return FALSE;
- /* Quit if text entry is NULL but select menu isn't. */
- if (text_null && new_module.select_menu != NULL)
- return FALSE;
-
- /* Checks passed OK, so record Select function for */
- /* this module. */
- module_fns[module_count].selectfn=new_module.selectfn;
-
- /* Install menu entry (if any) and sub-menu (if any). */
- if (!text_null)
- {
- if (!install_select_entry(new_module)) return FALSE;
- /* Set module_index to record that this module owns */
- /* the newly-installed entry in the Select menu. */
- module_index[module_count] = select_count;
- /* Ie, module m owns menu entry module_index[m] */
- }
- else
- /* Set module_index to record that this module does */
- /* not own an entry in the Select menu. */
- module_index[module_count] = NO_ENTRY;
-
- /*------------------------------------------------------*/
- /* Deal with Display function. */
- /*------------------------------------------------------*/
- /* Check for illegal combinations of NULL items. */
-
- text_null = (*new_module.display_entry == '\0');
- /* Quit if display fn is NULL but text entry isn't. */
- if (new_module.dispfn == NULL && !text_null)
- return FALSE;
- /* Quit if text entry is NULL but display menu isn't. */
- if (text_null && new_module.display_menu != NULL)
- return FALSE;
-
- /* Checks passed OK, so record Display function for */
- /* this module. */
- module_fns[module_count].dispfn = new_module.dispfn;
-
- /* Install menu entry (if any) and sub-menu (if any). */
- if (!text_null)
- if (!install_display_entry(new_module)) return FALSE;
-
- /*------------------------------------------------------*/
- /* Module installed OK */
- /*------------------------------------------------------*/
- /* Increment module count to show the no. of modules. */
- module_count++;
-
- return TRUE;
- }
-
-
- /*------------------------------------------------------*/
- /* Install Select menu entry for a Module. */
- /*------------------------------------------------------*/
- static BOOL install_select_entry(modulestr new_module)
- {
-
- /* Add text entry to menu. Use menu_new the first */
- /* time, and menu_extend thereafter. */
- if (select_count == 0)
- {
- sel_sub_menu = menu_new(SEL_SUB_NAME, new_module.select_entry);
- if (sel_sub_menu == NULL) return FALSE;
- }
- else
- menu_extend(sel_sub_menu, new_module.select_entry);
-
- /* Update sel_index array to associate new module */
- /* with this entry in the Select menu. */
- /* ie Entry n is owned by module sel_index[n] */
- sel_index[++select_count] = module_count;
-
- /* Set tick/fade status of menu entry, according to */
- /* whether module is enabled or disabled. */
- menu_setflags(sel_sub_menu, select_count, 0, !enabled[module_count]);
-
- /* Attach sub-menu, if one was provided. */
- if (new_module.select_menu != NULL)
- menu_submenu(sel_sub_menu, select_count, new_module.select_menu);
-
- return TRUE;
- }
-
- /*------------------------------------------------------*/
- /* Install Display menu entry for a Module. */
- /*------------------------------------------------------*/
- static BOOL install_display_entry(modulestr new_module)
- {
-
- /* Add text entry to menu. Use menu_new the first */
- /* time, and menu_extend thereafter. */
- if (display_count == 0)
- {
- display_sub_menu = menu_new(DISP_SUB_NAME, new_module.display_entry);
- if (display_sub_menu == NULL) return FALSE;
- }
- else
- menu_extend(display_sub_menu, new_module.display_entry);
-
- /* Update index array to associate new module with */
- /* this entry in the Display menu. */
- disp_index[++display_count] = module_count;
-
- /* Set ticked/faded status of menu entry, according */
- /* to whether module is enabled or disabled. */
- menu_setflags(display_sub_menu, display_count,\
- enabled[module_count], 0);
-
- /* Attach sub-menu, if one was provided. */
- if (new_module.display_menu != NULL)
- menu_submenu(display_sub_menu, display_count, new_module.display_menu);
-
- return TRUE;
- }
-
-
-
- /********************************************************/
- /* INITIALISATION */
- /********************************************************/
-
- static BOOL sv_initialise(void)
- {
- REAL big_r; /* Max dist from origin of Vert window */
- /* to any point in that window. */
- int compass_rad; /* Radius of Vert compass circle. */
- int i; /* General purpose counter. */
- REAL window_factor;/* Plotting scale calculated from */
- /* size of Horiz window. */
-
- /*------------------------------------------------------*/
- /* Read SkyView$Dir and form file name */
- /*------------------------------------------------------*/
- os_read_var_val("SkyView$Dir", app_dir, 245);
- if (*app_dir == '\0') return FALSE;
-
- /* Copy SkyView$Dir into array for file name. */
- strcpy(data_file, app_dir);
-
- /* Append file name */
- strcat(data_file, "." DEF_NAME);
-
- /*------------------------------------------------------*/
- /* Creation of menus */
- /*------------------------------------------------------*/
- /* Main menu structure. */
- if (main_menu=menu_new(MAIN_NAME, MAIN_MENU_ITEMS), \
- main_menu==NULL)
- return FALSE;
-
- /* Sub menu structure for 'View sel.'. */
- if (view_sub_menu=menu_new(VIEW_SUB_NAME, VIEW_SUB_MENU_ITEMS), \
- view_sub_menu==NULL)
- return FALSE;
-
- /* Attach 'View sel.' sub-menu. */
- menu_submenu(main_menu, item_view, view_sub_menu);
-
- /* Sub menu structure for 'Print'. */
- print_sub_menu = menu_new(PRINT_SUB_NAME, PRINT_SUB_MENU_ITEMS);
- if (print_sub_menu == NULL) return FALSE;
-
- /* Attach 'Print' sub-menu. */
- menu_submenu(main_menu, item_print, print_sub_menu);
-
- /*------------------------------------------------------*/
- /* Horizontal Window */
- /*------------------------------------------------------*/
- /* Create Horiz window */
- if (!create_window(HORIZ_NAME, &horiz_handle, &horiz_size))
- return FALSE;
-
- /* Initialise data structure for Horiz window */
- horiz_data.open = FALSE; /* Open/Closed flag */
- horiz_data.compass_drawfn = draw_horiz_compass; /* Compass-drawing fn */
- horiz_data.listptr = horiz_list; /* Point to plot list */
- horiz_data.number = 0; /* No objs. in list. */
- horiz_data.selnum = NOWHERE; /* No selected obj. */
- horiz_data.matrix.xx = 0; /* Transformation matrix*/
- horiz_data.matrix.xy = SCALFACT; /* for printing. Scale */
- horiz_data.matrix.yx = -SCALFACT; /* by SCALFACT and */
- horiz_data.matrix.yy = 0; /* rotate by 90°. */
- horiz_data.posn.dx = 540000; /* Position of print */
- horiz_data.posn.dy = 108000; /* rect. on page. */
- horiz_data.title_buildfn = build_horiz_title; /* Title-building fn. */
- horiz_data.title_writefn = write_horiz_title; /* Title-writing fn. */
-
- /* Register event handler for Horiz window */
- win_register_event_handler(horiz_handle, sv_win_event_handler, &horiz_data);
-
- /* Establish Menu Handler and Pre-menu Proc for Horiz. */
- if(!event_attachmenumaker(horiz_handle,main_premenuproc,main_menuproc,0))
- return FALSE;
-
- /* Establish screen scaling factor from */
- /* width of Horiz window. */
- width = (horiz_size.x1 - horiz_size.x0);
- window_factor = (REAL)width/((REAL)2.0*PI);
-
- /* Establish max altitude in Horiz window */
- height = horiz_size.y1;
- alt_max= (REAL)height/window_factor;
-
- /*------------------------------------------------------*/
- /* Vert Window */
- /*------------------------------------------------------*/
- /* Create Vert window */
- if (!create_window(VERT_NAME, &vert_handle, &vert_size))
- return FALSE;
-
- /* Initialise data structure for Vert window. */
- vert_data.open = FALSE; /* Open/Closed flag */
- vert_data.compass_drawfn = draw_vert_compass; /* Compass-drawing fn. */
- vert_data.listptr = vert_list; /* Point to plot list. */
- vert_data.number = 0; /* No objs. in list. */
- vert_data.selnum = NOWHERE; /* No selected obj. */
- vert_data.matrix.xx = SCALFACT; /* Transformation matrix*/
- vert_data.matrix.xy = 0; /* for printing. Scale */
- vert_data.matrix.yx = 0; /* by SCALFACT and */
- vert_data.matrix.yy = SCALFACT; /* rotate by 0°. */
- vert_data.posn.dx = 80000; /* Position of print */
- vert_data.posn.dy = 144000; /* rect. on page. */
- vert_data.title_buildfn = build_vert_title; /* Title-building fn. */
- vert_data.title_writefn = write_vert_title; /* Title-writing fn. */
-
- /* Register event handler for Vert window */
- win_register_event_handler(vert_handle, sv_win_event_handler, &vert_data);
-
- /* Establish Menu Handler and Pre-menu Proc for Vert. */
- if(!event_attachmenumaker(vert_handle,main_premenuproc,main_menuproc,0))
- return FALSE;
-
- /* Establish min altitude in Vert window. */
- /* First get maximum distance from origin to any point */
- /* in Vert window. */
- {
- int corner1, corner2, corner3, corner4;
- int r1, r2;
- int r_max;
- corner1 = vert_size.x0 * vert_size.x0 +
- vert_size.y0 * vert_size.y0;
- corner2 = vert_size.x0 * vert_size.x0 +
- vert_size.y1 * vert_size.y1;
- corner3 = vert_size.x1 * vert_size.x1 +
- vert_size.y0 * vert_size.y0;
- corner4 = vert_size.x1 * vert_size.x1 +
- vert_size.y1 * vert_size.y1;
- r1 = (corner1 > corner2 ? corner1 : corner2);
- r2 = (corner3 > corner4 ? corner3 : corner4);
- r_max = (r1 > r2 ? r1 : r2);
- big_r = (REAL)sqrt((double)r_max);
- }
- /* Can now calculate min altitude. */
- alt_min = PIby2 - big_r/window_factor;
- if (alt_min < (REAL)0.0)
- alt_min = (REAL)0.0;
-
- /* Construct a Draw Path consisting of a circle */
- /* and NDIR tick marks. */
-
- /* Set plotting factor to suit units used by Draw */
- /* functions. */
- factor = (REAL)DrawU * window_factor;
-
- /* Calculate radius of compass circle. */
- compass_rad = (int)(factor*(PIby2-compass_alt));
-
- /* Set up Path describing circle. */
- sv_Draw_circle(compass_rad);
-
- /* Set up Path describing NDIR tick marks. */
- for (i=0; i<NDIR; i++)
- {
- int x, y;
- xy_v(compass_alt, direction[i], &x, &y);
- sv_Draw_move(x,y);
- xy_v(compass_alt*(REAL)0.98, direction[i], &x, &y);
- sv_Draw_line(x,y);
- }
-
- /* Write end-of-path marker. */
- sv_Draw_endp();
-
- /* Process the Draw Path into a semi-digested form which*/
- /* will be quicker to plot (at the penalty of being */
- /* unable to take advantage of any increase in screen */
- /* resolution due to a later mode change). */
- draw_regsP.r[0] = (int)path; /* Input path. */
- draw_regsP.r[1] = (int)semi; /* Output path. */
- draw_regsP.r[2] = (int)&matrix; /* Transformation. */
- draw_regsP.r[3] = 0; /* Default flatness. */
- draw_regsP.r[4] = 4*DrawU; /* 4 OS units thick. */
- draw_regsP.r[5] = (int)&cj_style;/* Caps & joins. */
- draw_regsP.r[6] = 0; /* No dashes. */
- wimpt_noerr(os_swix(sv_XDraw_StrokePath, &draw_regsP));
-
- /* Set up register set for later call to plot the semi- */
- /* digested Path. */
- draw_regsS.r[0] = (int)semi; /* Input path. */
- draw_regsS.r[1] = 0x30; /* Fill only. Style. */
- draw_regsS.r[2] = 0; /* Transform 1:1 */
- draw_regsS.r[3] = 0; /* Flatness not used. */
- draw_regsS.r[4] = 0; /* Thickness not used.*/
- draw_regsS.r[5] = 0; /* Caps joins not used*/
- draw_regsS.r[6] = 0; /* No dashes. */
- draw_regsS.r[7] = 2; /* Fill by subpaths. */
-
- /* Set up register set for later call to print 'raw' */
- /* Draw Path (to take full advantage of printer resoln.)*/
- draw_regsP.r[1] = 0x30; /* Fill only. Style. */
-
- /* Set plotting factor to suit Horiz and Vert windows. */
- factor = window_factor;
-
- /*------------------------------------------------------*/
- /* Register current screen mode, and set sprite - */
- /* plotting tables. */
- /*------------------------------------------------------*/
- wimpt_checkmode();
- wimpt_noerr(sprite_tables());
-
- /*------------------------------------------------------*/
- /* dbox for Observer Details */
- /*------------------------------------------------------*/
-
- /* Create dbox */
- if (d_ob = dbox_new(OB_NAME), d_ob == NULL)
- return FALSE;
-
- /* Establish raw event handler */
- dbox_raw_eventhandler(d_ob, ob_raw_handler, 0);
-
- /* Find out window handle */
- ob_handle = (wimp_w)dbox_syshandle(d_ob);
-
- /* Attach menu & pre-menu proc */
- if(!event_attachmenumaker(ob_handle,main_premenuproc,main_menuproc,0))
- return FALSE;
-
- /* Set dbox fields to Factory Default Settings. */
- data_to_box(ob_data);
-
- /* Attempt to load user's default settings into dbox */
- /* from disc. */
- load_ob_data();
-
- /* Read observer details back from dbox. These will be */
- /* user's defaults if attempt to read was sucessful, and*/
- /* factory defaults otherwise. */
- data_from_box(&ob_data);
-
- /*------------------------------------------------------*/
- /* Info Box */
- /*------------------------------------------------------*/
-
- /* Create dbox. */
- if (d_info = dbox_new(INFO_NAME), d_info == NULL)
- return FALSE;
-
- /*------------------------------------------------------*/
- /* Icon Bar Icon */
- /*------------------------------------------------------*/
- /* Put icon on icon bar */
- /* and register icon click handler */
- baricon(ICON_NAME, 1, sv_iconclick);
-
- /* Establish icon menu handler */
- /* and menu pre-proc function */
- if(!event_attachmenumaker(win_ICONBAR,main_premenuproc,main_menuproc,0))
- return FALSE;
-
- /*------------------------------------------------------*/
- /* Registration of Modules */
- /*------------------------------------------------------*/
-
- if(!register_module(sun_initfn)) return FALSE;
- if(!register_module(moon_initfn)) return FALSE;
- if(!register_module(plans_initfn)) return FALSE;
- if(!register_module(star_initfn)) return FALSE;
- if(!register_module(markers_initfn)) return FALSE;
- if(!register_module(tvsats_initfn)) return FALSE;
- if(!register_module(userobj_initfn)) return FALSE;
-
- /* If there are any items in the Display sub-menu, */
- /* attach the sub-menu and unfade the Display item. */
- if (display_count > 0)
- {
- menu_submenu(main_menu, item_display, display_sub_menu);
- menu_setflags(main_menu, item_display, 0, 0);
- }
-
- /* If there are any items in the Select sub-menu, */
- /* attach the sub-menu. Unfading is handled by the */
- /* menumaker, as it depends on whether the user has */
- /* verified the observer details. */
- if (select_count > 0)
- menu_submenu(main_menu, item_select, sel_sub_menu);
-
- /*------------------------------------------------------*/
- /* End of Initialisation */
- /*------------------------------------------------------*/
- return TRUE;
- }
-
- /********************************************************/
- /* The MAIN function */
- /********************************************************/
-
- int main(int argc, char *argv[])
- {
- BOOL init_ok;
-
- if (argc>1) strcpy(start_file, argv[1]);
-
- /* RISC_OSlib initialisation */
- wimpt_init(APP_NAME); /* initialise task */
- res_init(APP_NAME); /* resources */
- resspr_init(); /* sprites */
- template_init(); /* templates */
- dbox_init(); /* dialogue boxes */
- visdelay_init(); /* hourglass */
-
- /* Other initialisation */
- visdelay_begin();
- init_ok = sv_initialise();
- visdelay_end();
-
- if (init_ok)
- {
- /* The main event loop */
- while (TRUE)
- event_process();
- }
-
- return 0;
- }
-